I'm fairly new to Haskell and have been trying to find a way to pass multiple IO-tainted values to a function to deal with a C library. Most people seem to use the <- operator inside a do block, like this:
g x y = x ++ y
interactiveConcat1 = do {x <- getLine;
y <- getLine;
putStrLn (g x y);
return ()}
This makes me feel like I'm doing C, except emacs can't auto-indent. I tried to write this in a more Lispy style:
interactiveConcat2 = getLine >>= (\x ->
getLine >>= (\y ->
putStrLn (g x y) >>
return () ))
That looks like a mess, and has a string of closed parentheses you have to count at the end (except again, emacs can reliably assist with this task in Lisp, but not in Haskell). Yet another way is to say
import Control.Applicative
interactiveConcat3 = return g <*> getLine <*> getLine >>= putStrLn
which looks pretty neat but isn't part of the base language.
Is there any less laborious notation for peeling values out of the IO taint boxes? Perhaps there is a cleaner way using a lift* or fmap? I hope it isn't too subjective to ask what is considered "idiomatic"?
Also, any tips for making emacs cooperate better than (Haskell Ind) mode would be greatly appreciated. Thanks!
John
Edit: I stumbled across https://wiki.haskell.org/Do_notation_considered_harmful and realized that the nested parentheses in the lambda chain I wrote is not necessary. However it seems the community (and ghc implementors) have embraced the Applicative-inspired style using , <*>, etc, which seems to make the code easier to read in spite of the headaches with figuring out operator precedence.