
Hello, So I've been trying to print some information in a file. I have two versions of the same function: one of them doesn't work and I don't understand why. Here are the functions: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -- This one works as intended when called from ghci renderTrackInfosToFile :: FilePath -> String -> IO [TrackInfos] -> IO () renderTrackInfosToFile filename sep ls = do nls <- ls writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) nls) return () -- This one does nothing when called from ghci renderTrackInfosToFile2 :: FilePath -> String -> [TrackInfos] -> IO () renderTrackInfosToFile2 filename sep ls = writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) ls) renderTrackInfo :: String -> TrackInfos -> String # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Both functions load in ghci, and the following commands are issued:
-- c :: IO [TrackInfos] liftM (renderTrackInfosToFile2 "blabla.txt" "|") c -- this command seems to do absolutely nothing renderTrackInfosToFile "blabla.txt" "|" c -- this one works as intended
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # And this is not the first time I have this sort of problem using liftM. I now that I'm missing something important here, can anyone explain me my mistake? Much thanks, Guillaume Basse

When you go with something like:
putStrLn "asdf" :: IO ()
but when you go:
liftM putStrLn (return "asdf") :: Monad m => m (IO ())
These are totally different. The first one is an IO action. The
second one is a monad that returns an IO action. When run in ghci,
ghci decides that the outer monad must be IO as well, so the type
becomes IO (IO ()). When you run that action, all you get is an IO ()
which has not been run and as such will not execute or print.
I'm not sure what you are attempting to get with liftM, but just make
sure to check out the final types of your statements with the :t
command in ghci and you should be able to figure it out.
On Wed, Jan 18, 2012 at 1:35 PM, Guillaume Basse
Hello,
So I've been trying to print some information in a file. I have two versions of the same function: one of them doesn't work and I don't understand why. Here are the functions:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-- This one works as intended when called from ghci renderTrackInfosToFile :: FilePath -> String -> IO [TrackInfos] -> IO () renderTrackInfosToFile filename sep ls = do nls <- ls writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) nls) return ()
-- This one does nothing when called from ghci renderTrackInfosToFile2 :: FilePath -> String -> [TrackInfos] -> IO () renderTrackInfosToFile2 filename sep ls = writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) ls)
renderTrackInfo :: String -> TrackInfos -> String
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
Both functions load in ghci, and the following commands are issued:
-- c :: IO [TrackInfos] liftM (renderTrackInfosToFile2 "blabla.txt" "|") c -- this command seems to do absolutely nothing renderTrackInfosToFile "blabla.txt" "|" c -- this one works as intended
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
And this is not the first time I have this sort of problem using liftM. I now that I'm missing something important here, can anyone explain me my mistake?
Much thanks,
Guillaume Basse
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

The one that's doing nothing is returning type IO (IO ()), which executes the outer IO (which is "c") and returns the inner IO (which is the contents of renderTrackInfosToFile2). You want a different combinator. Try playing with "join" and/or ">>=" (pronounced "bind") and you should be able to figure out ways to do it. Try looking at the types of liftM and liftM2 and see if you can figure out why they don't work. In ghci, try :t expression (:type expression) to find the type of any expression you input. The Control.Monad documentation has types of lots of convenient operations (look at the synopsis which has all their types together) (all of these operations are written using the basic operations of Monads.) http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.htm... By the way, 'liftM' is equivalent to 'fmap', if you're ever wondering. -Isaac On 01/18/2012 01:35 PM, Guillaume Basse wrote:
Hello,
So I've been trying to print some information in a file. I have two versions of the same function: one of them doesn't work and I don't understand why. Here are the functions:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-- This one works as intended when called from ghci renderTrackInfosToFile :: FilePath -> String -> IO [TrackInfos] -> IO () renderTrackInfosToFile filename sep ls = do nls<- ls writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) nls) return ()
-- This one does nothing when called from ghci renderTrackInfosToFile2 :: FilePath -> String -> [TrackInfos] -> IO () renderTrackInfosToFile2 filename sep ls = writeFile filename (intercalate "\n" $ map (renderTrackInfo sep) ls)
renderTrackInfo :: String -> TrackInfos -> String
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
Both functions load in ghci, and the following commands are issued:
-- c :: IO [TrackInfos] liftM (renderTrackInfosToFile2 "blabla.txt" "|") c -- this command seems to do absolutely nothing renderTrackInfosToFile "blabla.txt" "|" c -- this one works as intended
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
And this is not the first time I have this sort of problem using liftM. I now that I'm missing something important here, can anyone explain me my mistake?
Much thanks,
Guillaume Basse
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
David McBride
-
Guillaume Basse
-
Isaac Dupree