[Haskell-beginners] More direct binding of IO result

Michael Snoyman michael at snoyman.com
Sun May 15 08:55:06 CEST 2011


On Sun, May 15, 2011 at 9:49 AM, Arlen Cuss <celtic at sairyx.org> wrote:

> > -- Tried this and it didn't work.
> > main = do putStrLn (<- readFile "data.txt")
> >
>
> My question; how come fmap doesn's also work here? (though it's not a
> syntax-based solution):
>
> Prelude> fmap putStrLn (readFile "data.txt")
> Prelude>
>
> I thought it may have operated to make a new IO action, but if that were
> the case then ghci should have executed the result here.
>
>
Let's look at the types. Specializing to IO,

    readFile "data.txt" :: IO String

    fmap :: (a -> b) -> IO a -> IO b
    putStrLn :: String -> IO ()

    fmap putStrLn :: IO String -> IO (IO ())

Notice how there are now *two* IOs in "fmap putStrLn". Therefore, the result
of "fmap putStrLn (readFile "data.txt")" is of type "IO (IO ())".

The way to get rid of that extra IO is via the join function, which has type
(specialized for IO):

    join :: IO (IO a) -> IO a

So you could write:

    import Control.Monad (join)
    main = join (fmap putStrLn (readFile "data.txt"))

Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110515/a5e09824/attachment.htm>


More information about the Beginners mailing list