[project @ 2002-09-27 23:10:23 by erkok]
authorerkok <unknown>
Fri, 27 Sep 2002 23:10:23 +0000 (23:10 +0000)
committererkok <unknown>
Fri, 27 Sep 2002 23:10:23 +0000 (23:10 +0000)
The MonadRec.hs library, stolen from the Hugs release.

Note: There's a clear overlap with the library Control.Monad.Fix.

      Unfortunately, the names of the classes are different, mainly
      for historical reasons (MonadFix vs MonadRec.) There was some
      discussion on how to resolve this a while back, but I guess
      Hugs and GHC went their own ways. Once the dust settles, we
      can agree on something common, and make Hugs and GHC use the same
      names. (Note that this duplication also exists in the current
      release of Hugs as well.) For the time being, this file helps
      keep things simple with regard to the already existing code
      that uses the mdo-notation.. (i.e., it also defines instances
      for the LazyST, ST, and list monads in addition
      to the ones defined in Fix.hs: IO and maybe.)

We can also name this file just "Rec", but "MonadRec" sounds less
confusing, and more inline with the Hugs release.

Control/Monad/MonadRec.hs [new file with mode: 0644]

diff --git a/Control/Monad/MonadRec.hs b/Control/Monad/MonadRec.hs
new file mode 100644 (file)
index 0000000..00a8c26
--- /dev/null
@@ -0,0 +1,63 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.MonadRec
+-- Copyright   :  (c) Oregon Graduate Institute of Science and Technology, 2002
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org, erkok@cse.ogi.edu
+-- Stability   :  experimental
+-- Portability :  portable 
+--
+-- Declaration of the MonadRec class, and instances for
+-- maybe, list, IO, strict state, and lazy state monads
+--
+-- Note        : There's a clear overlap with the Control.Monad.Fix
+--        module, as they basically define the same structure
+--        with different names. The "MonadRec" name is kept
+--        here basically for compatibility with the current Hugs
+--        implementation. (Note that this duplication also exist 
+--        in the current Hugs release as well.)
+--
+-----------------------------------------------------------------------------
+
+module Control.Monad.MonadRec (
+       MonadRec(mfix)
+  ) where
+    
+import Prelude 
+import qualified Control.Monad.ST.Lazy as LazyST
+import qualified Control.Monad.ST as ST
+import System.IO
+
+fix :: (a -> a) -> a
+fix f = let a = f a in a
+
+-- The MonadRec class definition
+
+class Monad m => MonadRec m where
+    mfix :: (a -> m a) -> m a 
+
+-- Instances of MonadRec
+
+-- Maybe:
+instance MonadRec Maybe where
+    mfix f = let a = f (unJust a) in a
+             where unJust (Just x) = x
+
+-- List:
+instance MonadRec [] where
+    mfix f = case fix (f . head) of
+               []    -> []
+               (x:_) -> x : mfix (tail . f)
+
+-- IO:
+instance MonadRec IO where
+    mfix = fixIO 
+
+-- Lazy State:
+instance MonadRec (LazyST.ST s) where
+    mfix = LazyST.fixST
+    
+-- Strict State:
+instance MonadRec (ST.ST s) where
+    mfix = ST.fixST