[Haskell-beginners] Trying to find an alternative StateMonad
edgar klerks
edgar.klerks at gmail.com
Wed Apr 14 18:15:09 EDT 2010
Hi All,
I wanted to write the statemonad in a different way, because I want to
track mutations to the state. And also to be able to undo an done or
redo an undone mutation. Therefore I wrote a small dsl with an
evaluator, which finds out the current state.
The problem is, I don't know how to create a get and put function for
my monad. I have a function which evaluate the state and gives back
the current State.
Can someone help me a bit along? I have the feeling I do something
wrong, but I am not sure what.
With kind regards,
Edgar
{-# LANGUAGE GADTs,DeriveFunctor #-}
import Control.Monad
import Data.Maybe
data StateCmd a where
Put :: a -> StateCmd a
Undo :: StateCmd a
Redo :: StateCmd a
deriving (Show, Functor)
newtype State s a = State { unState :: ([StateCmd s],a) }
deriving Show
joinState :: State s a -> State s b -> State s b
joinState (State (xs, a)) (State (ys, b)) = State (xs ++ ys, b)
instance Monad (State s) where
return a = State $ ([], a)
(>>=) = bindState
-- m a -> ( a -> m b) -> m b
bindState st@(State (_,a)) f = st `joinState` st'
where st' = f a
unPut :: StateCmd a -> Maybe a
unPut (Put a) = Just a
unPut _ = Nothing
test = State $ ([Put 4, Undo, Redo, Undo, Put 5, Undo, Redo, Put 6,
Undo, Redo, Undo], ())
getCurrent = fromJust.unPut.head.snd.(foldr current'
([],[])).reverse.fst.unState
where current' x (ul,cl) = case x of
Put n -> (ul, Put n : cl)
Undo -> (head cl : ul, tail cl)
Redo -> (tail ul, head ul : cl)
More information about the Beginners
mailing list