Skip to content

Instantly share code, notes, and snippets.

@el-hult
Created July 1, 2021 09:13
Show Gist options
  • Save el-hult/8c821add91bfbac73f9fac2fb99ec3bd to your computer and use it in GitHub Desktop.
Save el-hult/8c821add91bfbac73f9fac2fb99ec3bd to your computer and use it in GitHub Desktop.
A simple While-loop in Haskell using the State Monad
-- Inspired by https://stackoverflow.com/questions/17719620/while-loop-in-haskell-with-a-condition
import Control.Monad.State
type IsZero = Bool
{-
This is in State monad. I.e. it is a function, that when given an initial state (Int,IsZero) will produce a tuple of ((Int,IsZero),())
We can see this as an action on our state space with no output value.
-}
decrementAndCheck :: State (Int, IsZero) ()
decrementAndCheck = do
(m,_) <- get
let n = m-1
put (n, n==0)
return ()
{-
This function applies some stateful processing decrementAndCheck
After each such processing, it makes a termination check on the state
In this specific example, it simply pulls the second component of the state
When that second component is True, we are done
Since we are in the state monad, the return type () really means ((Int,IsZero),())
and we can interrogate the final state if we like
-}
stateProcessor :: State (Int, IsZero) ()
stateProcessor = do
let loop True = return ()
loop False = do
decrementAndCheck
(_,isDone) <- get
loop isDone
loop False
main = print $ runState stateProcessor (12,False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment