monad-supply 0.6 → 0.9
raw patch · 3 files changed
Files
- README.md +37/−0
- monad-supply.cabal +40/−21
- src/Control/Monad/Supply.hs +78/−60
+ README.md view
@@ -0,0 +1,37 @@+++[](https://www.haskell.org/) [](http://hackage.haskell.org/package/monad-supply)++> A monad to support computations which consume values from a (possibly infinite) supply.++## Disclaimer++Please let me know if there is any issue with the licensing or copyright — I am assuming that, because the code appears on the HaskellWiki pages, it follows the [Simple license](https://wiki.haskell.org/HaskellWiki:Copyrights) found there, and that packaging it in this way is not a problem.++## About this library++I pulled this more or less verbatim from the HaskellWiki, since I wanted it on +Hackage for distribution purposes:++ http://www.haskell.org/haskellwiki/New_monads/MonadSupply++Some stuff was added, like a monoid instance and various helper functions.++ This library is based on code found on the HaskellWiki, and subject to the+ license found there:++ http://www.haskell.org/haskellwiki/HaskellWiki:Copyrights++ Permission is hereby granted, free of charge, to any person obtaining this+ work (the "Work"), to deal in the Work without restriction, including+ without limitation the rights to use, copy, modify, merge, publish,+ distribute, sublicense, and/or sell copies of the Work, and to permit+ persons to whom the Work is furnished to do so.++ THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+ FROM, OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS IN+ THE WORK.
monad-supply.cabal view
@@ -1,23 +1,42 @@-Name: monad-supply-Build-type: Simple-Version: 0.6-Cabal-Version: >= 1.6-Synopsis: Stateful supply monad.-Description: Support for computations which consume values from a (possibly infinite) supply.-License: OtherLicense-License-file: LICENSE-Category: Control, Data, Monads-Author: Geoff Hulette and unknown HaskellWiki contributor(s).-Maintainer: Geoff Hulette <ghulette@gmail.com>-Stability: experimental-Tested-With: GHC == 7.0.3+cabal-version: 1.12 -Library- Exposed-modules: Control.Monad.Supply- Hs-Source-Dirs: src- Build-Depends: base >= 4 && < 5,mtl >= 2- GHC-Options: -Wall+-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 39c53de256cb793f3b30bbe8f4c1d4e6bc458746ac18bbbb788ecb6cf7b7a265 -Source-Repository head- type: git- location: git://github.com/ghulette/monad-supply.git+name: monad-supply+version: 0.9+synopsis: Stateful supply monad+description: Support for computations which consume values from a (possibly infinite) supply.+category: Control, Data, Monad+stability: experimental+homepage: https://github.com/ghulette/monad-supply+bug-reports: https://github.com/ghulette/monad-supply/issues+author: Geoff Hulette and HaskellWiki contributors+maintainer: Geoff Hulette <geoff@hulette.net>+copyright: 2011-2020 Geoff Hulette and HaskellWiki contributors+license: OtherLicense+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md++source-repository head+ type: git+ location: https://github.com/ghulette/monad-supply++library+ exposed-modules:+ Control.Monad.Supply+ other-modules:+ Paths_monad_supply+ hs-source-dirs:+ src+ ghc-options: -Wall+ build-depends:+ base >=4.7 && <5+ , mtl >=2.2.2 && <3.0.0+ , transformers >=0.5.6.2 && <0.6.0.0+ default-language: Haskell2010
src/Control/Monad/Supply.hs view
@@ -1,82 +1,100 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-} -- | Support for computations which consume values from a (possibly infinite) -- supply. See <http://www.haskell.org/haskellwiki/New_monads/MonadSupply> for -- details.+ module Control.Monad.Supply-( MonadSupply (..)-, SupplyT-, Supply-, evalSupplyT-, evalSupply-, runSupplyT-, runSupply-, supplies-) where+ ( MonadSupply(..)+ , SupplyT+ , Supply+ , evalSupplyT+ , evalSupply+ , runSupplyT+ , runSupply+ , supplies+ ) where -import Control.Applicative-import Control.Monad.Identity-import Control.Monad.State-import Control.Monad.Error-import Control.Monad.Reader-import Control.Monad.Writer+import Control.Monad (replicateM)+import Control.Monad.Except (ExceptT, MonadError, throwError, catchError)+import Control.Monad.Fix (MonadFix)+import Control.Monad.IO.Class (MonadIO)+import Control.Monad.Reader (ReaderT)+import Control.Monad.State (StateT, get, gets, put, evalStateT, runStateT)+import Control.Monad.Trans (MonadTrans, lift)+import Control.Monad.Trans.Maybe (MaybeT)+import Control.Monad.Writer (WriterT)+#if !MIN_VERSION_base(4,11,0)+import Control.Monad.Fail (MonadFail)+import Data.Semigroup (Semigroup, (<>))+#endif +import qualified Control.Monad.Trans.State.Lazy as LazyState++ class Monad m => MonadSupply s m | m -> s where- supply :: m s- peek :: m s- exhausted :: m Bool+ supply :: m s+ peek :: m s+ exhausted :: m Bool -- | Supply monad transformer.-newtype SupplyT s m a = SupplyT (StateT [s] m a)- deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadFix)+newtype SupplyT s m a = SupplyT { unSupplyT :: StateT [s] m a }+ deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadFix) --- | Supply monad. -newtype Supply s a = Supply (SupplyT s Identity a)- deriving (Functor, Applicative, Monad, MonadSupply s, MonadFix)+instance MonadError e m => MonadError e (SupplyT s m) where+ throwError = lift . throwError+ catchError m h =+ SupplyT $ LazyState.liftCatch catchError (unSupplyT m) (unSupplyT . h) -instance Monad m => MonadSupply s (SupplyT s m) where- supply = SupplyT $ do (x:xs) <- get- put xs- return x- peek = SupplyT $ gets head- exhausted = SupplyT $ gets null+-- | Supply monad.+newtype Supply s a = Supply (SupplyT s Maybe a)+ deriving (Functor, Applicative, Monad, MonadSupply s, MonadFix) +instance MonadFail m => MonadSupply s (SupplyT s m) where+ supply = SupplyT $ do+ (x:xs) <- get+ put xs+ return x+ peek = SupplyT $ gets head+ exhausted = SupplyT $ gets null+ -- Monad transformer instances-instance (Error e,MonadSupply s m) => MonadSupply s (ErrorT e m) where- supply = lift supply- peek = lift peek- exhausted = lift exhausted+instance (MonadSupply s m) => MonadSupply s (ExceptT e m) where+ supply = lift supply+ peek = lift peek+ exhausted = lift exhausted instance MonadSupply s m => MonadSupply s (StateT st m) where- supply = lift supply- peek = lift peek- exhausted = lift exhausted+ supply = lift supply+ peek = lift peek+ exhausted = lift exhausted instance MonadSupply s m => MonadSupply s (ReaderT r m) where- supply = lift supply- peek = lift peek- exhausted = lift exhausted+ supply = lift supply+ peek = lift peek+ exhausted = lift exhausted +instance MonadSupply s m => MonadSupply s (MaybeT m) where+ supply = lift supply+ peek = lift peek+ exhausted = lift exhausted+ instance (Monoid w, MonadSupply s m) => MonadSupply s (WriterT w m) where- supply = lift supply- peek = lift peek- exhausted = lift exhausted+ supply = lift supply+ peek = lift peek+ exhausted = lift exhausted --- | Monoid instance for the supply monad. Actually any monad/monoid pair--- gives rise to this monoid instance, but we can't write its type like that--- because it would conflict with existing instances provided by Data.Monoid.---instance (Monoid a, Monad m) => Monoid (m a) where-instance (Monoid a) => Monoid (Supply s a) where- mempty = return mempty- m1 `mappend` m2 = do- x1 <- m1- x2 <- m2- return (x1 `mappend` x2)+instance Semigroup a => Semigroup (Supply s a) where+ m1 <> m2 = (<>) <$> m1 <*> m2 +instance (Semigroup a, Monoid a) => Monoid (Supply s a) where+ mempty = return mempty+ m1 `mappend` m2 = m1 <> m2+ -- | Get n supplies. supplies :: MonadSupply s m => Int -> m [s] supplies n = replicateM n supply@@ -84,11 +102,11 @@ evalSupplyT :: Monad m => SupplyT s m a -> [s] -> m a evalSupplyT (SupplyT s) = evalStateT s -evalSupply :: Supply s a -> [s] -> a-evalSupply (Supply s) = runIdentity . evalSupplyT s+evalSupply :: Supply s a -> [s] -> Maybe a+evalSupply (Supply s) = evalSupplyT s runSupplyT :: Monad m => SupplyT s m a -> [s] -> m (a,[s]) runSupplyT (SupplyT s) = runStateT s -runSupply :: Supply s a -> [s] -> (a,[s])-runSupply (Supply s) = runIdentity . runSupplyT s+runSupply :: Supply s a -> [s] -> Maybe (a,[s])+runSupply (Supply s) = runSupplyT s