fold on Monad?

C.Reinke C.Reinke@ukc.ac.uk
Wed, 29 May 2002 18:07:23 +0100


> Suppose I have a task I want to do to each line of a file,
> accumulate a result and output it, 
>..
> I'd like to write something similar to
> 
>    main = do res <- foldX process_line initial_value getLine
> 	           print res

> I feel this ought to be straightforward -- the structure is
> obviously some sort of fold, but I shouldn't have to use a
> list -- so I must be missing something obvious. What is it?

foldr, foldM, etc. derive a recursive computation from the recursive
structure of an input list, so you have to feed one in. If you want
to bypass the list, you could use IO-observations (getLine, isEOF)
instead of list observations (head/tail, null):

  import IO

  foldX f c = catch 
               (do l <- getLine
                   r <- foldX f c
                   return $ f l r)
               (\e->if isEOFError e 
                    then return c
                    else ioError e)
    
  main = foldX (:) [] >>= print

Whether that is a real fold, or what the real fold/unfold would
look like, I leave to others;-) The same goes for optimization.

Hth,
Claus