Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding monads into composites (Haskell)

Good day folks. I'm seeking some clarifications on monads please and using bind (while going into a composite .) please.

So for this example:

--Monadic parts:
readFile :: String -> IO File
putStr :: String -> IO()
-- Non monadic parts
toMatrix :: String -> CustomMatrix
toString :: CustomMatrix -> String

Essentially I'm lazily reading a file (readFile) then producing a custom matrix, converting the matrix to a string output. Then returning.

fileReading :: String -> IO
fileReading file = putStr(toString . toMatrix . readFile file)

This is when I start creating a mess by using bind >>= to go from readFile file. Is there a way I can continue to use composites . and bind and compose without making an unreadable mess (not really my aim).

As always, any help is gratefully received. Thanks folks.

like image 925
BrownE Avatar asked Mar 21 '13 17:03

BrownE


1 Answers

You can't get away without using some monadic function (like >>=) in this example. You can't use normal function composition with IO values if you actually want to end up doing some IO.

Happily, you can still write the code fairly readably:

fileReading file = readFile file >>= putStr . toString . toMatrix

This works because the two . operations combine two non-IO functions with a final IO function. At that point, you have two IO values: an IO String and a String -> IO () function (the entire putStr . toString . toMatrix expression has that type). This is exactly what >>= takes, so you're all set.

If you want the code to have the same order as above, you can use the backwards bind operator:

fileReading file = putStr . toString . toMatrix =<< readFile file

Some people find this version more readable because all of the code "flows" in the same direction.

like image 142
Tikhon Jelvis Avatar answered Sep 29 '22 05:09

Tikhon Jelvis