
Andrea Rossato wrote:
Now I'm trying to create a statefull evaluator, with output and exception, but I'm facing a problem I seem not to be able to conceptually solve.
data Eval_SOI a = Raise { unPackMSOIandRun :: State -> (a, State, Output) } | SOIE { unPackMSOIandRun :: State -> (a, State, Output) }
If you instead consider that you want the wrapped function to evaluate to a result that allows you to continue, or a result that is an exception, then you could use a flag to record whether or not an exception occurred eg: data Eval_SOI a = SOIE {runSOIE :: State -> (a, State, Output, Bool)} where the 4th element of the tuple is True iff we can continue or False iff an exception occurred.
raise x e = Raise (\s -> (x,s,e))
raise x e = SOIE {\s -> (x, s, e, False)} instance Monad Eval_SOI where return a = SOIE (\s -> (a, s, "", True)) m >>= f = SOIE $ \x -> let r1@(a, y, o1, ok1) = runSOIE m x in if ok1 then let (b, z, o2, ok2) = runSOIE (f a) y in (b, z, o1 ++ o2, ok2) else r1 ie if runSOIE m x does not result in an exception then we continue with the second computation otherwise we just return the exception (r1) immediately. Note I have not tested the above code so it may have a bug in it (also I renamed s1 and s2 to o1 and o2 to avoid confusion with the use of "s" to mean "state")... Regards, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com