[project @ 2004-08-09 12:00:34 by simonmar]
[ghc-base.git] / Control / Monad / Fix.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Control.Monad.Fix
4 -- Copyright   :  (c) Andy Gill 2001,
5 --                (c) Oregon Graduate Institute of Science and Technology, 2002
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  portable
10 --
11 -- The Fix monad.
12 --
13 --        Inspired by the paper
14 --        /Functional Programming with Overloading and
15 --            Higher-Order Polymorphism/, 
16 --          Mark P Jones (<http://www.cse.ogi.edu/~mpj/>)
17 --                Advanced School of Functional Programming, 1995.
18 --
19 -----------------------------------------------------------------------------
20
21 module Control.Monad.Fix (
22         MonadFix(
23            mfix -- :: (a -> m a) -> m a
24          ),
25         fix     -- :: (a -> a) -> a
26   ) where
27
28 import Prelude
29 import System.IO
30
31 fix :: (a -> a) -> a
32 fix f = let x = f x in x
33
34 class (Monad m) => MonadFix m where
35         mfix :: (a -> m a) -> m a
36
37 -- Instances of MonadFix for Prelude monads
38
39 -- Maybe:
40 instance MonadFix Maybe where
41     mfix f = let a = f (unJust a) in a
42              where unJust (Just x) = x
43
44 -- List:
45 instance MonadFix [] where
46     mfix f = case fix (f . head) of
47                []    -> []
48                (x:_) -> x : mfix (tail . f)
49
50 -- IO:
51 instance MonadFix IO where
52     mfix = fixIO