[project @ 2002-10-01 10:32:11 by ross]
[ghc-base.git] / Control / Monad / MonadRec.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Control.Monad.MonadRec
4 -- Copyright   :  (c) Oregon Graduate Institute of Science and Technology, 2002
5 -- License     :  BSD-style (see the file libraries/base/LICENSE)
6 --
7 -- Maintainer  :  libraries@haskell.org, erkok@cse.ogi.edu
8 -- Stability   :  experimental
9 -- Portability :  portable 
10 --
11 -- Declaration of the MonadRec class, and instances for
12 -- maybe, list, IO, strict state, and lazy state monads
13 --
14 -- Note : There's a clear overlap with the Control.Monad.Fix
15 --        module, as they basically define the same structure
16 --        with different names. The "MonadRec" name is kept
17 --        here basically for compatibility with the current Hugs
18 --        implementation. (Note that this duplication also exist 
19 --        in the current Hugs release as well.)
20 --
21 -----------------------------------------------------------------------------
22
23 module Control.Monad.MonadRec (
24         MonadRec(mfix)
25   ) where
26     
27 import Prelude 
28 import qualified Control.Monad.ST.Lazy as LazyST
29 import qualified Control.Monad.ST as ST
30 import System.IO
31
32 fix :: (a -> a) -> a
33 fix f = let a = f a in a
34
35 -- The MonadRec class definition
36
37 class Monad m => MonadRec m where
38     mfix :: (a -> m a) -> m a 
39
40 -- Instances of MonadRec
41
42 -- Maybe:
43 instance MonadRec Maybe where
44     mfix f = let a = f (unJust a) in a
45              where unJust (Just x) = x
46
47 -- List:
48 instance MonadRec [] where
49     mfix f = case fix (f . head) of
50                []    -> []
51                (x:_) -> x : mfix (tail . f)
52
53 -- IO:
54 instance MonadRec IO where
55     mfix = fixIO 
56
57 -- Lazy State:
58 instance MonadRec (LazyST.ST s) where
59     mfix = LazyST.fixST
60     
61 -- Strict State:
62 instance MonadRec (ST.ST s) where
63     mfix = ST.fixST