packages feed

monad-supply 0.6 → 0.9

raw patch · 3 files changed

Files

+ README.md view
@@ -0,0 +1,37 @@+![logo](supply_monad.png)++[![Language](https://img.shields.io/badge/language-Haskell-yellow.svg)](https://www.haskell.org/) [![Hackage](https://img.shields.io/hackage/v/monad-supply.svg)](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