[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,)
> 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
> 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).
More information about the Haskell-Cafe