
David Menendez wrote:
So it might be possible to rewrite your code along these lines:
type M = StateT State []
run :: Foo -> M ()
runOr :: Foo -> Foo -> M () runOr x y = mplus (run x) (run y)
runAnd :: Foo -> Foo -> M () runAnd x y = run x >> run y
The type "StateT State [] alpha" is isomorphic to "State -> [(alpha, State)]", which means that each of the computations in mplus gets its own copy of the state.
There are a few ways to add exceptions to this, depending on how you want the exceptions to interact with the non-determinism.
2. StateT State (NondetT (Either ErrorType)) alpha
I have some longwinded code that works, but I'm still thinking about how to do this more elegantly. It looks like what I really need is something like type M = StateT State (ResultSetT (ErrorT ErrorType Identity)) Is that the correct ordering? If so, I guess that means I have to somehow construct ResultSetT. Is there an easy way to do that, given that I already have ResultSet? For example, if I put ResultSet into Traversable, would that let me do it?