|
|
|
|
|
by tsuraan
2559 days ago
|
|
OP is somewhat conflating two different things: non-strict function evaluation and lazy IO. With lazy IO, you can get, for example, a String from a file. That string is actually a lazily-constructed chain of Cons cells, so if you're into following linked lists and processing files one char at a time, then it's fun to use. The dangerous bit comes in when you close the file after evaluating its contents as a string: fd <- open "/some/path"
s <- readContentsLazy fd
close fd
pure $ processString s
Now, processString is getting a string with the file's contents, right? Nope, you have a cons cell that probably contains the first character of the file, and maybe even a few more up to the first page that got read from disk, but eventually as you're processing that string, you'll hit a point where your pure string processing actually tries to do IO on the file that isn't open anymore, and your perfect sane and pure string processing code will throw an exception. So, that's gross.That's a real issue that will hit beginners. There's been a lot of work done to make ergonomic and performant libraries that handle this without issues; I think that right now pipes[0] and conduit[1] are the big ones, but it's a space that people like to play with. [0] - https://hackage.haskell.org/package/pipes
[1] - https://github.com/snoyberg/conduit |
|
In other words the problem seems to be (in this example) that the standard library mixes lazy and strict semantics. A better library wouldn’t carry that flaw.