I believe that the “Backtracking, Interleaving and Terminating Monad Transformers” (functional gem) of Kiselev, Shan and Friedman describes the solution.
Disclaimer: I am not an expert in this work!
Basically, you should use a different monad. Since the ListT monad transformer does depth - at first, they came up with the new LogicT monad LogicT , which makes the width first. (If you are not interested in monad transformers, you can simply apply the transformer to Id to return the normal monad).
First, they recognize the flaws in other approaches:
a simple depth search performed by most MonadPlus implementations is unfair: the non-deterministic choice between the two alternatives tries each solution from the first alternative before any solution from the second alternative. When the first alternative offers an infinite number of solutions, the second alternative has never been tried, making the search incomplete. Indeed, as our examples in section 3 show, a fair retreat helps to stop more logical programs.
[...]
The second flaw in many existing backrex monks is the adoption of the Prologue cut, which mixes negation with cropping. Theoretically, each of the negatives and truncations independently makes logical programming languages more expressive
[...]
A third practical flaw is the often forgotten top-level interface: how to run and interact with a calculation that can return an infinite number of answers? The most common solution is to provide a stream that can be consumed or processed at the top level as desired. But in the case of monad transformers, this solution only works if the base monad is not strict (for example, the nuns Haskells lazy list and LazyST). In the case of a strict base monad, the estimation may diverge, forcing to evaluate the entire flow, even if we need only one answer.
They then present a solution based on the LogicT monad transformer LogicT msplit function. Although the code link is broken, I searched Hoogle for LogicT and found this .
I hope that reading this article will give you good experience in this topic and help you understand how to use the projects that you have already found.
If you find this article useful, be sure to check out its links and other documents that cite it!