No Description

HelloMonads.hs 2.1KB

    {- - Hello, Monads! - - Exploring what Monads mean (in Haskell). -} import Prelude hiding (Maybe(..), print, putStr, putStrLn, getLine, getContent) -- define Maybe here so we can implement our own monad data Maybe a = Just a | Nothing deriving (Show, Eq, Ord) instance Monad Maybe where (Just x) >>= action = action x Nothing >>= action = Nothing -- apparently optional: -- maybeA >> maybeB = maybeA >>= \_ -> maybeB return x = Just x -- FIXME: fail? -- fail _ = Nothing maybeAdd m1 m2 = m1 >>= \x -> m2 >>= \y -> return (x + y) maybeAdd' m1 m2 = do x <- m1 y <- m2 return $ x + y type InputState = String type OutputState = String -- * Model IO as a function of the previous state to a new state and a result. -- -- If you look closely (i.e. execute `:i IO` in ghci), you'll notice -- that this is a simplification of the real IO type. -- Of course it is missing file handles, actual output and other -- gimmicks, but it gives an idea of what IO does (and why). data WeirdIO a = WeirdIO ((InputState, OutputState) -> ((InputState, OutputState), a)) executeWeirdIO :: InputState -> WeirdIO a -> ((InputState, OutputState), a) executeWeirdIO input (WeirdIO f) = {-snd . fst $-} f (input, "") instance Monad WeirdIO where (WeirdIO changeState) >>= action = WeirdIO $ \state -> let ((i, o), x) = changeState state (WeirdIO f) = action x in f ((i, o)) return x = WeirdIO $ \state -> (state, x) print :: Show a => a -> WeirdIO () print x = putStrLn $ show x putStr, putStrLn :: String -> WeirdIO () putStr s = WeirdIO $ \(i, o) -> ((i, o ++ s), ()) putStrLn s = putStr $ s ++ "\n" getChar :: WeirdIO Char getChar = WeirdIO $ \(c:cs, o) -> ((cs, o), c) getLine, getContent :: WeirdIO String getLine = WeirdIO $ \(i, o) -> (((dropUntil (== '\n') i), o), takeWhile (/= '\n') i) getContent = WeirdIO $ \(i, o) -> (("", o), i) takeUntil :: (a -> Bool) -> [a] -> [a] takeUntil p [] = [] takeUntil p (x:xs) = if (p x) then [x] else x : takeUntil p xs dropUntil p [] = [] dropUntil p (x:xs) = if (p x) then xs else dropUntil p xs