Last active
April 10, 2020 01:55
-
-
Save rajanaresh/ee319f51c1a52c5c6e7c093eb1b940f6 to your computer and use it in GitHub Desktop.
Comparison b/w my implementation of FizzBuzz using my own State Monad with my own "mapM_" (myMapM_) and the implementation from the Haskell book
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/stack | |
{- stack | |
--resolver lts-14.27 | |
exec ghci | |
--package pretty-simple | |
-} | |
import Control.Monad | |
import Control.Monad.Trans.State | |
fizzBuzz :: Integer -> String | |
fizzBuzz n | n `mod` 15 == 0 = "FizzBuzz" | |
| n `mod` 5 == 0 = "Buzz" | |
| n `mod` 3 == 0 = "Fizz" | |
| otherwise = show n | |
fizzBuzzList :: [Integer] -> [String] | |
fizzBuzzList ls = execState (mapM_ addResult ls) [] | |
where addResult :: Integer -> State [String] () | |
addResult n = get >>= | |
\s -> put (fizzBuzz n: s) | |
-- the main function is slightly different in the book but I am using this | |
main :: IO () | |
main = traverse putStrLn (fizzBuzzList [1..100]) >> | |
return () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/stack | |
{- stack | |
--resolver lts-14.27 | |
exec ghci | |
--package pretty-simple | |
-} | |
newtype State s a = State { runState :: s -> (a, s) } | |
instance Functor (State s) where | |
fmap f (State sa) = State $ \s -> (f (fst (sa s)), snd (sa s)) | |
instance Applicative (State s) where | |
pure x = State $ \s -> (x, s) | |
-- (<*>) :: State s (a -> b) -> State s a -> State s b | |
State sf <*> State sa = State $ \s -> ((fst (sf s)) (fst (sa s)), s) | |
instance Monad (State s) where | |
return = pure | |
-- (>>=) :: State s a -> a -> State s b -> State s b | |
-- (>>=) :: (s -> (a, s)) -> (a -> (s -> (b, s))) -> s -> (b, s) | |
State sa >>= aSb = State $ \s -> runState (aSb (fst (sa s))) s | |
myMapM_ :: (Foldable t) => (a -> State s ()) -> t a -> State s () | |
myMapM_ f ls = foldr go (return ()) ls | |
where go x y = copy y >>= \st -> State $ \s -> runState (f x) st | |
fizzBuzz :: Integer -> String | |
fizzBuzz n | n `mod` 15 == 0 = "FizzBuzz" | |
| n `mod` 5 == 0 = "Buzz" | |
| n `mod` 3 == 0 = "Fizz" | |
| otherwise = show n | |
fizzBuzzS :: Integer -> State [String] () | |
fizzBuzzS n = get >>= | |
\s -> put (fizzBuzz n: s) | |
fizzBuzzList :: [Integer] -> [String] | |
fizzBuzzList ls = execState (myMapM_ fizzBuzzS ls) [] | |
put :: s -> State s () | |
put s = State $ \_ -> ((), s) | |
get :: State s s | |
get = State $ \s -> (s, s) | |
execState :: State s () -> s -> s | |
execState st s = snd (runState st s) | |
copy :: State s () -> State s s | |
copy st = State $ \s -> (execState st s, execState st s) | |
main :: IO () | |
main = traverse putStrLn (fizzBuzzList [1..100]) >> | |
return () | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
State monad implementation is wrong
Should be
State sa >>= aSb = State $ \s -> runState (aSb (fst (sa s))) (snd (sa s))