StateMonad.icl 1.91 KB
Newer Older
Diederik van Arkel's avatar
Diederik van Arkel committed
1 2
implementation module StateMonad

3 4
// a general-purpose state monad (implemented by macros)

Diederik van Arkel's avatar
Diederik van Arkel committed
5
:: StateM state a
6
	:== state -> *(a, state)
Diederik van Arkel's avatar
Diederik van Arkel committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

/*

result :: a -> StateM .state a
result x
  = result`
  where
	result` state = (x, state)

(>>>=) infixl :: (StateM .state a) (a -> StateM .state b) -> StateM .state b
(>>>=) ma f
  = bindWithResult
  where
	bindWithResult state
	  # (a, state`) = ma state
	  = f a state`

(>>>) infixl :: (StateM .state a) (StateM .state b) -> StateM .state b
(>>>) ma mb
  = bindWithoutResult
  where
	bindWithoutResult state
	  # (_, state`) = ma state
	  = mb state`

*/

mapl :: (a -> StateM state b) ![a] -> StateM state [b]
mapl f []
  = result []
mapl f [a:as]
  = f a				>>>= \b ->
	mapl f as		>>>= \bs ->
	result [b:bs]

skip :== result nothing

IF guard _ thenBranch _ elseBranch :== if guard thenBranch elseBranch
THEN :== 0
ELSE :== 0

nothing :: nothing
nothing = nothing

mfoldr :: (a b -> StateM state b) b ![a] -> StateM state b
mfoldr op e [] 
  = result e
mfoldr op e [a:as]
  = mfoldr op e as >>>= \b ->
	op a b

runState		:: state !(StateM state a)				-> (a,state)
runState state f
  = f state

onlyIf :: !Bool (StateM .env nothing) -> StateM .env nothing
onlyIf True  monad	= monad
onlyIf False _		= skip

sequence :: ![StateM s a] -> StateM s [a]
sequence [] = result []
sequence [x:xs] = x >>>= \y -> sequence xs >>>= \ys -> result [y:ys]

mmap :: (a -> b) (StateM s a) -> StateM s b
mmap f ma = ma >>>= \a -> result (f a)

mWhile :: (StateM s Bool) (StateM s a) -> StateM s [a]
mWhile cond action
  = cond >>>= \bool ->
    if bool
    (
      action             >>>= \a ->
      mWhile cond action >>>= \as ->
      result [a:as]
    )
    (
      result []
    )

/* MACRO VERIONS OF RESULT AND BIND  */

result x :== \state -> (x, state)

(>>>=) infixl 
(>>>=) ma f  :== \state -> let (a, state`) = ma state in f a state`

(>>>) infixl
(>>>) ma mb :== \state -> let (_, state`) = ma state in mb state`