Personal tools

New monads/MonadUnique

From HaskellWiki

< New monads(Difference between revisions)
Jump to: navigation, search
m
 
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
From [[NewMonads]], copied from [http://haskell.org/hawiki/MonadUnique old wiki].
+
[[Category:Code]]
 
+
From New monads, copied from [http://haskell.org/hawiki/MonadUnique old wiki].
= MonadUnique =
+
  
 
This is a simple (trivial) monad transformer for supplying unique integer values to an algorithm.
 
This is a simple (trivial) monad transformer for supplying unique integer values to an algorithm.
  
[http://haskell.org/hawiki/CaleGibbard_2fBSDLicense "CaleGibbard/BSDLicense"]
+
==MonadUnique==
 
+
 
<haskell>
 
<haskell>
 
{-# OPTIONS_GHC -fglasgow-exts #-}
 
{-# OPTIONS_GHC -fglasgow-exts #-}
Line 40: Line 38:
 
evalUniqueT (UniqueT s) = evalStateT s 0
 
evalUniqueT (UniqueT s) = evalStateT s 0
 
evalUnique (Unique s) = runIdentity (evalUniqueT s)
 
evalUnique (Unique s) = runIdentity (evalUniqueT s)
 +
</haskell>
 +
 +
== STSupply ==
 +
 +
There is also a simple way to get the same functionality in the ST Monad. Here's a quick module to construct infinite supplies of unique values in the ST monad:
 +
 +
<haskell>
 +
module STSupply (Unique, createSupply) where
 +
 +
import Control.Monad.ST
 +
import Data.STRef
 +
 +
newtype Unique = Unique Integer deriving (Eq, Ord)
 +
 +
createSupply :: ST s (ST s Unique)
 +
createSupply = do
 +
    v <- newSTRef $ Unique 0
 +
    return $ do
 +
        Unique x <- readSTRef v
 +
        writeSTRef v $ Unique (x+1)
 +
        return $ Unique x
 +
</haskell>
 +
 +
A test example:
 +
 +
<haskell>
 +
import Control.Monad.ST
 +
import STSupply
 +
 +
main = print test1
 +
 +
test1 = runST supplyTest
 +
    where supplyTest = do
 +
              fresh <- createSupply
 +
              x <- fresh
 +
              y <- fresh
 +
              return (x == x, x == y, x < y)
 
</haskell>
 
</haskell>

Latest revision as of 07:33, 10 December 2006

From New monads, copied from old wiki.

This is a simple (trivial) monad transformer for supplying unique integer values to an algorithm.

[edit] 1 MonadUnique

{-# OPTIONS_GHC -fglasgow-exts #-}
 
module MonadUnique
        ( UniqueT,
          Unique,
          MonadUnique,
          fresh,
          evalUniqueT,
          evalUnique )
    where
 
import Control.Monad
import Control.Monad.State
import Control.Monad.Identity
 
newtype UniqueT m a = UniqueT (StateT Integer m a)
    deriving (Functor, Monad, MonadTrans, MonadIO)
 
newtype Unique a = Unique (UniqueT Identity a)
    deriving (Functor, Monad, MonadUnique)
 
class Monad m => MonadUnique m where
    fresh :: m Integer
 
instance (Monad m) => MonadUnique (UniqueT m) where
    fresh = UniqueT $ do
                n <- get
                put (succ n)
                return n
 
evalUniqueT (UniqueT s) = evalStateT s 0
evalUnique (Unique s) = runIdentity (evalUniqueT s)

[edit] 2 STSupply

There is also a simple way to get the same functionality in the ST Monad. Here's a quick module to construct infinite supplies of unique values in the ST monad:

module STSupply (Unique, createSupply) where
 
import Control.Monad.ST
import Data.STRef
 
newtype Unique = Unique Integer deriving (Eq, Ord)
 
createSupply :: ST s (ST s Unique)
createSupply = do
    v <- newSTRef $ Unique 0
    return $ do
        Unique x <- readSTRef v
        writeSTRef v $ Unique (x+1)
        return $ Unique x

A test example:

import Control.Monad.ST
import STSupply
 
main = print test1
 
test1 = runST supplyTest
    where supplyTest = do
              fresh <- createSupply
              x <- fresh
              y <- fresh
              return (x == x, x == y, x < y)