Created
July 1, 2021 09:13
-
-
Save el-hult/8c821add91bfbac73f9fac2fb99ec3bd to your computer and use it in GitHub Desktop.
A simple While-loop in Haskell using the State Monad
This file contains hidden or 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
-- 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