haskell - State Monad with multiple state values -
consider following:
do x1 <- new 2 set x1 3 x2 <- x1 y1 <- new 10 set y1 20 y2 <- y1 return (x2 + y2) i want result in 23. there way implement in pure haskell, , if how? understand stref this, want in ordinary haskell (not worried efficiency @ moment). presume i'll have make data type , make instance of monad, i'm not sure of details, working example helpful.
this allows more 1 value, it's hairier :) nicely simplified daniel's suggestion of dynamic.
import data.dynamic import data.maybe import control.monad.state import data.map m newtype ref = ref {ref :: int} type mutstate = state (int, map int dynamic) val :: typeable => ref -> mutstate val r = snd `fmap` >>= return . fromjust . (>>= fromdynamic) . m.lookup (ref r) new :: typeable => -> mutstate (ref a) new = (curr, binds) <- put (curr + 1, m.insert (curr + 1) (todyn a) binds) return . ref $ curr + 1 set :: typeable => ref -> -> mutstate () set (ref i) = (c, m) <- put (c, m.insert (todyn a) m) runmut :: mutstate -> runmut = flip evalstate (0, m.fromlist []) then use it
default (int) -- lazy signatures :) test :: int test = runmut $ x1 <- new 2 set x1 3 x2 <- val x1 y1 <- new 10 set y1 20 y2 <- val y1 return (x2 + y2) refs ints type information attached , val appropriate dynamic , attempt force correct type.
if real code, should hide implementations of ref , mutstate. convenience, i've fromjusted return of val bur if want safe implementation suppose layer state , maybe monads deal unbound variables.
and in case worried typeable constraints, shown above trivially derived.
Comments
Post a Comment