[Haskell-cafe] How to print a string (lazily)

Chris Kuklewicz haskell at list.mightyreason.com
Tue Jan 3 12:45:48 EST 2006


Daniel Carrera wrote:
> Hello,
> 
> I've been studying more Haskell and I've improved a lot. But I just hit
> a small problem. I want to print all the elements of a linst (putStr).
> I'd like to write something like this:
> 
> print_list [] = do putStr ""
> print_list (x:xs) = (do putStr x) && print_list xs
> 
> I know this is wrong, but I hope you can see what I'm trying to do.
> 
> I know of other ways I could print a list. For example:
> 
> print_list xs = do putStr(join xs)
>     where join [] = ""
>           join (x:xs) = (show x) ++ "\n" ++ join xs
> 
> But the thing is, I want to write a lazy version of this function. It's
> not that I need such a function, I'm just trying to learn Haskell.
> 
> Any suggestions?
> 
> Question: What do you call a function that has side-effects? (like
> putStr) I know that "function" is the wrong term.
> 
> Cheers,
> Daniel.

I sometimes call a function with side-effects in IO a "command".  But
the terms are fungible.  But calling putStr a "function" is correct.  It
is not a "pure function" however.

What does lazy printing mean?

I assume it means you evaluate the head of the list, print it, then
recursively do this for the tail of the list.  With an infinite list you
will get inifinite output.

I assume it does not mean you evaluate the whole list before printing
anything.  This would prevent infinite lists from producing output.

(mapM_ putStr) or (mapM_ putStrLn) will do what you want.

All of these commands show work, even if hw is inifitely long:

let printList [] = return ()
    printList (x:xs) = do putStrLn x
                          printList xs

main = do
  let hw = ["Hello"," ","World","!"]
  mapM_ putStr hw
  mapM_ putStrLn hw
  putStr (unlines hw) -- see also: unwords, words, lines
  printList hw

-- 
Chris


More information about the Haskell-Cafe mailing list