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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With