Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created October 1, 2010 06:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snoyberg/605826 to your computer and use it in GitHub Desktop.
Save snoyberg/605826 to your computer and use it in GitHub Desktop.
import Prelude hiding (head)
import Data.Enumerator
import Control.Monad.IO.Class
sum1 :: [Int] -> Int
sum1 [] = 0
sum1 (x:xs) = x + sum xs
getNumber :: IO (Maybe Int)
getNumber = do
x <- getLine
if x == "q"
then return Nothing
else return $ Just $ read x
sum2 :: IO Int
sum2 = do
maybeNum <- getNumber
case maybeNum of
Nothing -> return 0
Just num -> do
rest <- sum2
return $ num + rest
getNumber2 :: IO (Stream Int)
getNumber2 = do
maybeNum <- getNumber -- using the original getNumber function
case maybeNum of
Nothing -> return EOF
Just num -> return $ Chunks [num]
sum3 :: IO Int
sum3 = do
stream <- getNumber2
case stream of
EOF -> return 0
Chunks nums -> do
let nums' = sum nums
rest <- sum3
return $ nums' + rest
sum4 :: IO (Stream Int) -> IO Int
sum4 getNum = do
stream <- getNum
case stream of
EOF -> return 0
Chunks nums -> do
let nums' = sum nums
rest <- sum4 getNum
return $ nums' + rest
sum5 :: Monad m => Step Int m Int -- Int input, any monad, Int output
sum5 =
Continue $ go 0 -- a common pattern, you always start with a Continue
where
go :: Monad m => Int -> Stream Int -> Iteratee Int m Int
-- Add the new input to the running sum and create a new Continue
go runningSum (Chunks nums) = do
let runningSum' = runningSum + sum nums
-- This next line is *ugly*, good thing there are some helper
-- functions to clean it up. More on that below.
Iteratee $ return $ Continue $ go runningSum'
-- Produce the final result
go runningSum EOF = Iteratee $ return $ Yield runningSum EOF
sum6 :: Monad m => Iteratee Int m Int
sum6 = do
maybeNum <- head
case maybeNum of
Nothing -> return 0
Just i -> do
rest <- sum6
return $ i + rest
lazyIO :: IO ()
lazyIO = do
s <- lines `fmap` getContents
mapM_ putStrLn s
interleaved :: MonadIO m => Iteratee String m ()
interleaved = do
maybeLine <- head
case maybeLine of
Nothing -> return ()
Just line -> do
liftIO $ putStrLn line
interleaved
head' :: Monad m => Iteratee a m (Maybe a)
head' =
continue go
where
go (Chunks []) = continue go
go (Chunks (x:xs)) = yield (Just x) (Chunks xs)
go EOF = yield Nothing EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment