Skip to content

Instantly share code, notes, and snippets.

@cideM
Last active January 4, 2019 18:58
Show Gist options
  • Save cideM/b74a28db4abe5d6d17371e2573c4dfb3 to your computer and use it in GitHub Desktop.
Save cideM/b74a28db4abe5d6d17371e2573c4dfb3 to your computer and use it in GitHub Desktop.
Understanding state monad in relation to replicateM
#!/usr/bin/env stack
{-
stack
script
--resolver lts-12.20
--package mtl,text,monad-loops
-}
{-# LANGUAGE OverloadedStrings #-}
import qualified Control.Monad as M
import Control.Monad.State (State)
import qualified Control.Monad.State as S
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Debug.Trace as D
-- S.runState listDoReplicate [2] -> (10,[17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2])
listDoReplicate :: State [Int] Int
listDoReplicate = do
nums <- S.get
let nextNum = head nums + 1
S.put (nextNum : nums)
if nextNum < 10
then head <$> M.replicateM 2 listDoReplicate
else return nextNum
-- This is exactly the same listDoReplicate since I took it from -ddump-simple
dumped :: State [Int] Int
dumped =
S.get >>=
(\nums ->
let nextNum = head nums + 1
in S.put (nextNum : nums) >>
if nextNum < 10
then head <$> S.replicateM 2 dumped
else return nextNum)
easy :: State [Int] Int
easy = head <$> S.replicateM 2 state
where
state = do
nums <- S.get
let nextNum = head nums + 1
S.put (nextNum : nums)
return nextNum
{-
listDoReplicate
|
| - recurse 3
| - recurse 4
| - recurse 5
| - recurse 6
| - recurse 7
| - recurse 8
| - recurse 9
| - return 10
| - recurse 11
| - recurse 12
| - recurse 13
| - recurse 14
| - recurse 15
| - recurse 16
| - recurse 17
-}
main = do
let s = S.runState listDoReplicate [2]
TIO.putStrLn . T.pack $ show s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment