Skip to content

Instantly share code, notes, and snippets.

@fero23
Created January 28, 2016 21:28
Show Gist options
  • Save fero23/faaceab9c5494407fb91 to your computer and use it in GitHub Desktop.
Save fero23/faaceab9c5494407fb91 to your computer and use it in GitHub Desktop.
A small state monad example demonstrating the creation of a number stream collection accumulated in a string
type State = (String, Integer)
data ST x = S(State -> (x, State))
apply st (S f) = f st
instance Functor ST where
fmap f (S f') = S(\s -> let (x, s') = f' s in (f x, s'))
instance Applicative ST where
pure x = S(\s -> (x, s))
(S f) <*> s = S(\s' -> let (S f') = fmap (\x -> (fst $ f s') x) s in f' s')
instance Monad ST where
return x = S(\s -> (x, s))
(S f) >>= f' = S(\s -> let (x, s') = f s in apply s' $ f' x)
double = S(\(acc, last) -> let n = last * 2 in (n, (acc ++ "\n" ++ show n, n)))
triple = S(\(acc, last) -> let n = last * 3 in (n, (acc ++ "\n" ++ show n, n)))
comment str = S(\(acc, last) -> (last, (acc ++ "\n" ++ str, last)))
streamOps :: ST Integer
streamOps = do
first <- double
double
third <- triple
comment $ "The first and third operation results are " ++ show first ++ " and " ++ show third
triple
end <- double
comment $ "The stream ends with " ++ show end
intStreamString :: String
intStreamString = let (_, (str, _)) = apply ("--Start--", 1) streamOps in str
main = putStrLn intStreamString
-- Main results:
{-
--Start--
2
4
12
The first and third operation results are 2 and 12
36
72
The stream ends with 72
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment