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)
?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With