Haskell IO - file lines to list -
I am writing a hascal program and having trouble with IO types. It seems that something is wrong with my readLines function and the way it wants to return I want to return a list where each element has a line from the file that has been opened with the openDict function.
This is my code.
main :: IO () main = do fileHandle & lt; - openDict readLines fileHandle putStr "end of program \ n" readLines :: handle - & gt; [Io string] readLines fileHandle | IEOF & LT; - HISF file handle = [] | Otherwise = [hGetLine fileHandle] ++ readlines fileHandle openDict :: IO handle openDict = do puttr "Enter the file path:" filePath & lt; - GetLine OpenFile File Path ReadModa
Here is an error:
With type 'IO' type '[]' can not be matched with expected type: IO (IO String) Actual Type: [IO String] 'readlines' in the return type of call STMT of a 'Do' block: readLines fileHandle expression: do {fileHandle & lt; - openDict; Move ReadLines file; PutStr "End of the program"}
So basically, how can I store these stars from the IO in the list?
There are several problems with your readLines
function
First of all, in this case you do not want to return to [IO String]
. This will be a list of IO actions such as [print 1> & Gt; Return "a", print 2 & gt; & Gt; You need a single IO action to return a list of
string
s so you do not want to return to IO [String]
.
need to be used. Second, pattern guard isf & lt; - The hIsEOF file handle is checking that the value returned by
hIsEOF
is the isEOF
form (which is an IO action), where IsEOF
Defining a variable is still OK some form var
, because one variable can be anything. That's why the test is always right, and not meaningful: for example, the IO operation also does not work.
Thirdly, the way you add list creators and Io functions, it follows the current wrong type, so it is quite confusing.
A very popular way of achieving this will be instead:
readLines :: handle - & gt; IO [String] readLines fileHandle = do eof & lt; - hIsEOF file handle if eof returns again [else] line & lt; - hGetLine file handles comfort & lt; - readLines FileHandle Returns (Line: Rest)
The last rows can be truncated using the implementer
syntax:
import control Enforceable readLines2 :: handles - & gt; IO [string] readLines2 fileHandle = do eof & lt; - hIsEOF file handles if eof returns [] else (:) & lt; $ & Gt; HGetLine file handles & lt; * & Gt; ReadLines2 fileHandle
Instead of reading everything in a file and using the line
library function in lists, a smaller version can be obtained.
import control. Functional readLines3 :: handles - & gt; Io [string] readLines3 filehandle = lines & lt; $ & Gt; HGetContents file handles
Comments
Post a Comment