In a recent paper, Launchbury, Lewis, and Cook observe that some Haskell applications could benefit from a combinator mfix for expressing recursion over monadic types. We investigate three possible definitions of mfix and implement them in Haskell.
Like traditional fixpoint operators, there are two approaches to the definition of mfix: an unfolding one based on mathematical semantics, and an updating one based on operational semantics. The two definitions are equivalent in pure calculi but have different behaviors when used within monads.
The unfolding version can be easily defined in Haskell if one restricts fixpoints to function types. The updating version is much more challenging to define in Haskell despite the fact that its definition is straightforward in Scheme. After studying the Scheme definition in detail, we mirror it in Haskell using the primitive unsafePerformIO. The resulting definition of mfix appears to work well but proves to be unsafe, in the sense that it breaks essential properties of the purely functional subset of Haskell. We conclude that the updating version of mfix should be treated as a monadic effect. This observation leads to a safe definition based on monad transformers that pinpoints and exposes the subtleties of combining recursion with other effects and puts them under the programmer's control to resolve as needed.
The conclusion is that Haskell applications that need the functionality of mfix can be written safely in any Haskell dialect that supports the multi-parameter classes necessary for defining monad transformers. No other extensions to standard Haskell are needed, although some syntactic abstractions and libraries can make the task of writing recursive monadic bindings much more convenient.