listhaskellmonadsmonadfix

MonadFix instance for []


The instance is defined as

instance MonadFix [] where
  mfix f = case fix (f . head) of
             []    -> []
             (x:_) -> x : mfix (tail . f)

But I'm failing to grasp the intuitive meaning behind it with respect to the [] monad seen as non-deterministic computations. In mfix f function f must not be strict in its argument, so it can't examine the argument. And according to the definition it also can't use the argument anywhere in its output, otherwise at some point it'll hit fix (f . head) and diverge. So is there any use (or good example) for mfix for lists, other than mfix (const someList)?


Solution

  • It's probably easiest to say it like this. The functions f for which mfix f is totally defined are those for which the spine of f x does not depend on x, so they can be written in the form

    f x = [f1 x, ..., fn x]
    

    for some n (possibly infinity) and some f1, ..., fn. Then

    mfix f = [fix f1, ..., fix fn]
    

    (of course for this to really be totally defined, each fix fi must also be defined).


    mfix can be thought of as nondeterministically giving you the fixed point of a nondeterministic function. The rather heavy restriction is that the shape of the nondeterministic computation cannot depend in any way on the input. We seem to need some kind of restriction on the computation in order to get started, but you might hope to at least be able to kill off a branch of the computation conditionally (say if some intermediate calculation is negative). I've always thought that it should be possible to use mfix in this way by using a different nondeterminism monad whose choice operation is not associative, but never worked out the details.