ANN: LocallyLazyRead-0.1 Repository: http://www.patch-tag.com/r/exit/LocallyLazyRead/home
(no hackage package since anonymous uploads are not allowed there) The package comprises just one function which applies a lazy parser to a resource that may otherwise be accessed via strict IO: > import Control.LocallyLazyRead Assume a (lazy) parser: > parse :: Read a => String -> IO (a,String) > parse = return . head . reads Turn this into a "get"-like function which reads the characters strictly but computes the parse result lazily: > foo :: Handle -> IO (String,Char,(Int,Int),Char) > foo h = do > s <- llread (hGetChar h) parse > c1 <- hGetChar h > ii <- llread (hGetChar h) parse > c2 <- hGetChar h > return (s,c1,ii,c2) where llread is of type IO t -> ([t] -> IO (a,[t])) -> IO a The parser must satisfy the following semantic constraint: For all finite p, arbitrary q, arbitrary a with the right type: (parse (p++q)) computes the value (a,q) in a given IO state if and only if (parse p) computes the value (a,[]) in the same IO state This entails zero lookahead into the unparsed rest, and also a rest which truely depends on the input - parse x = return (x,[]) is forbidden. Violations are detected at runtime: > -- throws a LookaheadAttempt exception: > bar :: Handle -> IO Bool > bar h = llread (hGetChar h) (\(y:ys)-> return (isSpace y,y:ys)) > -- throws a Lookahead exception: > barbar :: Handle -> IO Int > barbar h = llread (hGetChar h) parse --- e(x(i(t))) <e.ex.exi.e...@gmail.com> Key fingerprint = A915 1EA1 4D0E 759A B925 0076 A409 2713 E490 3776 _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell