Use a better ListT
turion opened this issue · 10 comments
The ListT
implementation we're using (from transformers
) is wrong (it's just m [a]
) and we should eventually settle for a different, correct version.
What would the behaviour of other versions be?
Following https://wiki.haskell.org/ListT_done_right, it would be like so:
-- The monadic list type
data MList' m a = MNil | a `MCons` MList m a
type MList m a = m (MList' m a)
-- This can be directly used as a monad transformer
newtype ListT m a = ListT { runListT :: MList m a }
By the way, this is isomorphic to our MStream
. It interleaves one effect of m
with one element of the list.
Also, is this the reason that Control.Monad.Trans.MSF.List
is not listed in dunai.cabal
? (Because it's deemed incorrect?)
I don't see any reason not to list it. If there ever was one, I can't recall.
So, the difference is how the effects in the monad m
get unfolded (one by one vs all at once).
Yes. Although I don't see anything wrong with ListT
only working for commutative monads in principle.
So, essentially, it is possible to obtain the current behaviour with a helper function:
listT2List :: ListT m a -> m [a]
listT2List = mlistT2List . runListT
mlistT2List :: MList m a -> m [a]
mlistT2List MNil = return []
mlistT2List (MCons a listT) = do
as <- mlistT2List listT
return (a : as)
And, probably:
mlistT2List = reverse . foldM (\xs a -> return (a:xs)) []
I also see no reason not to support the so-called broken ListT
. So this ticket could be "provide combinators/lifting/running functions for another list transformer".
This currently is not bugging me at all. I can either close it and you can re-open when it becomes the one issue you (@turion ) are actively working on, or assign it to you and forget about it.
This issue has been stagnated for over 3 years. I'm closing it.