Skip to content

Commit 78eaa5c

Browse files
committed
Finally finished ch 23
1 parent da7ebfa commit 78eaa5c

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

ch23/ChapterExercises.hs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
3+
newtype State s a =
4+
State { runState :: s -> (a, s) }
5+
6+
instance Functor (State s) where
7+
fmap f (State g) = State $ \s -> let (a, s') = g s
8+
in (f a, s')
9+
10+
instance Applicative (State s) where
11+
(State f) <*> (State g) = State $ \s -> let (h, s') = f s
12+
(a, s'') = g s'
13+
in (h a, s'')
14+
15+
pure a = State $ \ s -> (a, s)
16+
17+
instance Monad (State s) where
18+
(State f) >>= g = State $ \s -> let (a, s') = f s
19+
State h = g a
20+
in h s'
21+
22+
return = pure
23+
24+
25+
get :: State s s
26+
get = State $ \ s -> (s, s)
27+
28+
put :: s -> State s ()
29+
put s = State $ const ((), s)
30+
31+
exec :: State s a -> s -> s
32+
exec s = snd . runState s
33+
34+
eval :: State s a -> s -> a
35+
eval s = fst . runState s
36+
37+
modify :: (s -> s) -> State s ()
38+
modify f = f <$> get >>= put

ch23/FizzBuzz.hs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
import Control.Monad
3+
import Control.Monad.Trans.State
4+
5+
import qualified Data.DList as DL
6+
7+
import Data.Foldable
8+
9+
fizzBuzz :: Integer -> String
10+
fizzBuzz n | n `mod` 15 == 0 = "FizzBuzz"
11+
| n `mod` 5 == 0 = "Buzz"
12+
| n `mod` 3 == 0 = "Fizz"
13+
| otherwise = show n
14+
15+
16+
17+
18+
fizzbuzzList :: [Integer] -> DL.DList String
19+
fizzbuzzList list = execState (mapM_ addResult list) DL.empty
20+
21+
addResult :: Integer -> State (DL.DList String) ()
22+
addResult n = do
23+
xs <- get
24+
let result = fizzBuzz n
25+
put (DL.snoc xs result)
26+
27+
fizzbuzzFromTo :: Integer -> Integer -> [String]
28+
fizzbuzzFromTo from to = execState (mapM_ addR' [to, to-1 .. from]) []
29+
30+
addR' :: Integer -> State ([String]) ()
31+
addR' n = do
32+
xs <- get
33+
let result = fizzBuzz n
34+
put (result : xs)
35+
36+
main :: IO ()
37+
main = do
38+
let a = toList $ fizzbuzzList $ [1 .. 100]
39+
b = fizzbuzzFromTo 1 100
40+
41+
print $ a == b
42+
43+
{-main :: IO ()-}
44+
{-main = traverse_ (putStrLn . fizzBuzz) [1..100]-}

ch23/Moi.hs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
3+
newtype Moi s a =
4+
Moi { runMoi :: s -> (a, s) }
5+
6+
instance Functor (Moi s) where
7+
fmap f (Moi g) = Moi $ \s -> let (a, s') = g s
8+
in (f a, s')
9+
10+
instance Applicative (Moi s) where
11+
(Moi f) <*> (Moi g) = Moi $ \s -> let (h, s') = f s
12+
(a, s'') = g s'
13+
in (h a, s'')
14+
15+
pure a = Moi $ \ s -> (a, s)
16+
17+
instance Monad (Moi s) where
18+
(Moi f) >>= g = Moi $ \s -> let (a, s') = f s
19+
Moi h = g a
20+
in h s'
21+
22+
return = pure

ch23/ThrowDown.hs

+5-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ intToDie n =
2626
x -> error $ "intToDie got non 1-6 integer: " ++ show x
2727

2828
rollDieThreeTimes :: (Die, Die, Die)
29-
rollDieThreeTimes = do
29+
rollDieThreeTimes =
3030
let s = mkStdGen 0
3131
(d1, s1) = randomR (1, 6) s
3232
(d2, s2) = randomR (1, 6) s1
3333
(d3, _) = randomR (1, 6) s2
34-
(intToDie d1, intToDie d2, intToDie d3)
34+
in (intToDie d1, intToDie d2, intToDie d3)
3535

3636
rollDie :: State StdGen Die
3737
rollDie = state $ do
@@ -45,9 +45,12 @@ rollDieThreeTimes' :: State StdGen (Die, Die, Die)
4545
rollDieThreeTimes' =
4646
liftA3 (,,) rollDie' rollDie' rollDie'
4747

48+
49+
-- Repeats a single value
4850
infiniteDie :: State StdGen [Die]
4951
infiniteDie = repeat <$> rollDie
5052

53+
-- What you actually want
5154
nDie :: Int -> State StdGen [Die]
5255
nDie n = replicateM n rollDie
5356

0 commit comments

Comments
 (0)