concrete functor and monad transformers
#99SelectT not productive for most base monads
While the Hedges paper that is the origin of Control.Monad.Trans.Select explicitly mentions the (sequence.repeat)
construction, it seems for most base monads this yields divergent code. Minimal example:
import Control.Monad (guard)
type K = SelectT () Maybe
zeroes = sequenceA (repeat (pure 0 :: K Int))
diverges = fmap (take 2) $ runSelectT zeroes (guard.const True)
I tested this both with the SelectT implementation of the latest transformers package and with the original implementation in the Hedges paper. Thus it is not the fault of the library implementation, but at the least unintended and undocumented behaviour. I reached out to Jules Hedges for comment.
I suspect the cause is strictness of the base monad's bind. With Identity
as the base monad, sequence.repeat
constructions are indeed productive.
It seems the issue is *
sequence.repeat
is not productive with strict monads, and *SelectT r m
is strict if and only ifm
is.Indeed that seems to be the cause. Since by virtue of
lift
the strictness of the base monad is likely preserved by any transformer, we can not expectSelectT r m
to perform better thanm
. Does the transformers package have any policy regarding strictness analysis? I feel we should at least add a warning in the Haddocks, since infinite lists were one of the showcases in the Hedges paper.