For any MonadLogic instance, we can write
gather :: MonadLogic m => m a -> m [a]
gather m = msplit m >>= \case
Nothing -> pure []
Just (a, m') -> (a:) <$> gather m'
However, this is inefficient for LogicT when producing many results, due to the recursive use of msplit. For LogicT, we can simply write
gather = lift . observeAllT
This can also be implemented easily to ReaderT. I haven't looked into other transformers because I didn't need them for my work.
One option would be to add gather as a LogicT method. The fact that it always accumulates a list doesn't seem ideal, however. Is there some nice way to generalize it that would allow both lazy and strict accumulation?
For any
MonadLogicinstance, we can writeHowever, this is inefficient for
LogicTwhen producing many results, due to the recursive use ofmsplit. ForLogicT, we can simply writeThis can also be implemented easily to
ReaderT. I haven't looked into other transformers because I didn't need them for my work.One option would be to add
gatheras aLogicTmethod. The fact that it always accumulates a list doesn't seem ideal, however. Is there some nice way to generalize it that would allow both lazy and strict accumulation?