Search code examples
haskellfixpoint-combinators

How to understand/use Haskell fix function


I see the following code in xmonad package:

-- | Ignore SIGPIPE to avoid termination when a pipe is full, and SIGCHLD to
-- avoid zombie processes, and clean up any extant zombie processes.
installSignalHandlers :: MonadIO m => m ()
installSignalHandlers = io $ do
    installHandler openEndedPipe Ignore Nothing
    installHandler sigCHLD Ignore Nothing
    (try :: IO a -> IO (Either SomeException a))
      $ fix $ \more -> do
        x <- getAnyProcessStatus False False
        when (isJust x) more
    return ()

It seems that this fix functions comes from Data.Function

But I can't understand how it's used here and when would someone use this fix function?


Solution

  • fix is the fundamental tool used for implementing recursion. It can always be replaced by a recursive let -- and vice versa, a recursive let can be turned into a call to fix. In this example,

    fix $ \more -> do
        x <- getAnyProcessStatus False False
        when (isJust x) more
    

    is equivalent to

    let more = do
            x <- getAnyProcessStatus False False
            when (isJust x) more
    in more
    

    and is essentially implementing a loop that calls getAnyProcessStatus False False until it returns Nothing.