Difference between revisions of "New monads/MonadSupply"

From HaskellWiki
Jump to navigation Jump to search
m (Remove redundant link)
(fix import)
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
  +
[[Category:Code]]
From New monads, copied from [http://haskell.org/hawiki/MonadSupply old wiki]
 
 
= MonadSupply =
 
 
   
 
Here is a simple monad/monad transformer for computations which consume values from a (finite or infinite) supply. Note that due to pattern matching, running out of supply in a non-MonadZero monad will cause an error.
 
Here is a simple monad/monad transformer for computations which consume values from a (finite or infinite) supply. Note that due to pattern matching, running out of supply in a non-MonadZero monad will cause an error.
 
[http://haskell.org/hawiki/CaleGibbard_2fBSDLicense "CaleGibbard/BSDLicense"]
 
   
 
<haskell>
 
<haskell>
Line 22: Line 17:
 
where
 
where
 
import Control.Monad
 
import Control.Monad
  +
import Control.Monad.Identity
 
import Control.Monad.State
 
import Control.Monad.State
   
Line 27: Line 23:
 
deriving (Functor, Monad, MonadTrans, MonadIO)
 
deriving (Functor, Monad, MonadTrans, MonadIO)
   
newtype Supply s a = Supply (SupplyT s Maybe a)
+
newtype Supply s a = Supply (SupplyT s Identity a)
 
deriving (Functor, Monad, MonadSupply s)
 
deriving (Functor, Monad, MonadSupply s)
   

Latest revision as of 05:09, 4 April 2014


Here is a simple monad/monad transformer for computations which consume values from a (finite or infinite) supply. Note that due to pattern matching, running out of supply in a non-MonadZero monad will cause an error.

{-# OPTIONS_GHC -fglasgow-exts #-}

module MonadSupply 
    (SupplyT,
     MonadSupply,
     supply,
     Supply,
     evalSupplyT,
     evalSupply,
     runSupplyT,
     runSupply)
    where
import Control.Monad
import Control.Monad.Identity
import Control.Monad.State

newtype SupplyT s m a = SupplyT (StateT [s] m a)
    deriving (Functor, Monad, MonadTrans, MonadIO)

newtype Supply s a = Supply (SupplyT s Identity a)
    deriving (Functor, Monad, MonadSupply s)

class Monad m => MonadSupply s m | m -> s where
    supply :: m s
    
instance Monad m => MonadSupply s (SupplyT s m) where
    supply = SupplyT $ do
                (x:xs) <- get
                put xs
                return x

evalSupplyT (SupplyT s) supp = evalStateT s supp
evalSupply (Supply s) supp = evalSupplyT s supp

runSupplyT (SupplyT s) supp = runStateT s supp
runSupply (Supply s) supp = runSupplyT s supp

As an example, if we want to supply unique strings for use as variable names, the following specialisation of runSupply (or its obvious analogue with runSupplyT) might be handy:

runSupplyVars x = runSupply x vars
    where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence