[Haskell-cafe] Lifting makes lazy

Jeremy Shaw jeremy.shaw at linspireinc.com
Thu Sep 16 13:08:42 EDT 2004


At Thu, 16 Sep 2004 18:26:35 +0200,
hjgtuyl at chello.nl wrote:
> 
> 
> L.S.,
> 
> In my enthusiasm to reduce imperative style coding to a minimum, I changed  
> a program to something too lazy to do anything. The following is an  
> extremely simplified version of the program:
> 
> > import Monad
> 
> > displayFile1 :: IO (IO ())displayFile1 =  liftM putStr contents --  
> > Displays nothing
> >     where
> >       contents :: IO [Char]
> >       contents = readFile "DisplayFile.lhs"
> 
> This should display the contents of a file, but nothing appears. The  
> following function should be exactly the same, but this one does display  
> the file:
> 
> > displayFile2 :: IO ()
> > displayFile2 =  do
> >     contents <- readFile "DisplayFile.lhs"
> >     putStr contents
> 
> My conclusion is, that "putStr" is evaluated strictly, while "liftM  
> putStr" is not.

Has nothing to do with strict/lazy.

> I have the following questions:
>   - Why is this difference?


Notice the type of displayFile1 vs displayFile2

	IO(IO()) vs IO ()

While displayFile2 actually prints something, displayFile1 mearly
returns an 'action', which will print something if you 'evaluate' it.

Here is an example of how to use displayFile1 the way you wrote it:

import Monad

displayFile1 :: IO (IO ())
displayFile1 =  liftM putStr contents
    where
      contents :: IO [Char]
      contents = readFile "DisplayFile.lhs"


doDisplayFile :: IO ()
doDisplayFile = displayFile1 >>= \action -> action

or alternately, you could write doDisplayFile like this (same thing,
just a different syntax):

doDisplayFile :: IO ()
doDisplayFile = 
 do action <- displayFile1
    action


if you wanted displayFile1 to behave more like displayFile2 you could
write it like this:

displayFile3 :: IO ()
displayFile3 = contents >>= putStrLn
    where
      contents :: IO [Char]
      contents = readFile "DisplayFile.lhs"

or, like this (same thing, different syntax)

displayFile3 :: IO ()
displayFile3 = 
	do c <- contents
	   putStrLn c
    where
      contents :: IO [Char]
      contents = readFile "DisplayFile.lhs"

Jeremy Shaw
--

This message contains information which may be confidential and privileged. Unless you are the 
addressee (or authorized to receive for the addressee), you may not use, copy or disclose to anyone 
the message or any information contained in the message. If you have received the message in error, 
please advise the sender and delete the message.  Thank you.


More information about the Haskell-Cafe mailing list