[project @ 2002-10-01 10:32:11 by ross]
[packages/old-time.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