[Haskell-cafe] Lazy Lists and IO

Felipe Almeida Lessa felipe.lessa at gmail.com
Wed Jul 11 02:48:54 EDT 2007


On 7/11/07, Stefan O'Rear <stefanor at cox.net> wrote:
> Not very nicely.
>
> Option 1. Ignore purity
> Option 2. Ignore lists

Option 3. Use continuations

You maintein purity while keeping flexibility. One possible implementation:

> data Result a = Finished (a, [a])
>               | NeedInput (a -> Result a)

It's on the NeedInput where we hide the input list. If a for some
cutoff and some list there were needed n elements, then there will be
(n-1) NeedInput's, one for each except for the first. After the last
one, the Result will be Finished.

> accumUntilCutoff  :: (Ord a, Num a) => a -> a -> Result a
> accumUntilCutoff = acc (0,[])
>     where
>       acc (s,p) cutoff x
>           | x >= cutoff = Finished (s+x,reverse $ x:p)
>           | otherwise   = NeedInput (acc (s+x,x:p) (cutoff-x))

Note how we explicity "traverse" on the "list".

> readUntilCutoff :: (Ord a, Num a, Read a) => a -> IO (a,[a])
> readUntilCutoff cutoff = get >>= parse . accumUntilCutoff cutoff
>     where
>       get = putStr "Enter an integer: " >> getLine >>= return . read
>       parse (Finished (s,p)) = return (s,p)
>       parse (NeedInput f)    = get >>= parse . f

Probably there's a better way of using continuations, but I think this
suffices (and works).

Cheers,

-- 
Felipe.


More information about the Haskell-Cafe mailing list