<div dir="ltr">If you want to use monad transformers and have Either e [a] as the result type then you need Either to be the inner monad and List to be the outer monad. If you look at the types of EitherT (from the either package) and ListT from transformers this should hopefully make sense. Then you would keep the same impl as you have now, only you would need to "run" the ListT computation to yield Either e [a]. Anything that you would like to do inside of the inner Error monad will need to lifted inside of it using lift. Does that help you at all?<div><br></div><div>Ben</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 5 Oct 2015 at 11:06 Mario Lang <<a href="mailto:mlang@delysid.org">mlang@delysid.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi.<br>
<br>
Consider this structure:<br>
<br>
vs :: Rational -> [Input] -> [[Output]]<br>
vs _ []     = return []<br>
vs l (x:xs) = pms l x >>= \pm -> (pm :) <$> vs (l - dur pm) xs<br>
<br>
pms :: Rational -> Input -> [Output]<br>
pms l x = [x, x+1, x+2, ...] -- Just an example, not real code.<br>
                             -- in reality, l is used to determine<br>
                             -- the result of pms.<br>
<br>
This is basically traverse, but with a state (l) added to it.<br>
So without the state, vs could be written as<br>
<br>
vs = traverse pms<br>
<br>
Now, I want to add Either e to this, like:<br>
<br>
vs :: Rational -> [Input] -> Either e [[Output]]<br>
pms :: Rational -> Input -> Either e [Output]<br>
<br>
However, I have no idea how to implement vs.<br>
<br>
Interestingly, adding Either e to vs without changing the code lets it<br>
compile, but it gives me the wrong result:<br>
<br>
vs :: Rational -> [Input] -> Either e [[Output]]<br>
vs _ []     = return []<br>
vs l (x:xs) = pms l x >>= \pm -> (pm :) <$> vs (l - pm) xs<br>
<br>
Since I am in the Either monad now, >>= does not do non-determinism, it<br>
simply unwraps the Either from pms.  I have to admit, I dont fully<br>
understand why this compiles, and what exactly it does wrong.  I only<br>
see from testing that the results can't be right.<br>
<br>
On IRC, Gurkenglas suggested to use the State monad, like this:<br>
<br>
vs :: Rational -> [Input] -> Either e [[Output]]<br>
vs l = `evalStateT l` . mapM v where<br>
  v x = do l <- get<br>
           pm <- lift $ pms l x<br>
           put (l - dur pm)<br>
           return pm<br>
<br>
This compiles, but also yields unexpected results.<br>
<br>
I have invested several hours now trying to add Either around this<br>
algorithm, so that I can emit hard failures.  I am sort of frustrated<br>
and out of ideas.  Somehow, I can't figure out what these<br>
transformations actually change in behaviour.  I am being told, by quite<br>
experienced Haskell programmers, that this is supposed to be correct,<br>
but my testing tells me otherwise.  So before I just give up on this,<br>
could someone please have a look and let me know if I have missed<br>
something obvious?<br>
<br>
--<br>
CYa,<br>
  ⡍⠁⠗⠊⠕<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>