generator 0.5.2 → 0.5.3
raw patch · 4 files changed
+24/−93 lines, 4 filesdep ~ListPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: List
API changes (from Hackage documentation)
- Control.Monad.Consumer: consumeRestM :: (Monad m) => ConsumerT a m b -> ConsumerT a m (m b)
- Control.Monad.Consumer: data ConsumerT v m a
- Control.Monad.Consumer: evalConsumerT :: (List l) => ConsumerT v (ItemM l) a -> l v -> ItemM l a
- Control.Monad.Consumer: instance (Monad m) => Applicative (ConsumerT v m)
- Control.Monad.Consumer: instance (Monad m) => Functor (ConsumerT v m)
- Control.Monad.Consumer: instance (Monad m) => Monad (ConsumerT v m)
- Control.Monad.Consumer: instance (MonadIO m) => MonadIO (ConsumerT v m)
- Control.Monad.Consumer: instance MonadTrans (ConsumerT v)
- Control.Monad.Consumer: next :: (Monad m) => ConsumerT v m (Maybe v)
- Control.Monad.DList: instance (Monad m) => List (DListT m)
+ Control.Monad.DList: joinDListT :: (Monad m) => m (DListT m a) -> DListT m a
+ Control.Monad.DList: toListT :: (Monad m) => DListT m a -> ListT m a
Files
- generator.cabal +4/−5
- src/Control/Monad/Consumer.hs +0/−73
- src/Control/Monad/DList.hs +8/−8
- src/Control/Monad/Generator.hs +12/−7
generator.cabal view
@@ -1,10 +1,10 @@ Name: generator-Version: 0.5.2+Version: 0.5.3 Category: Control Synopsis: Python-generators notation for creation of monadic lists Description:- Consumer and Generator monad transformers to create- and iterate 'ListT's in a manner similar to+ Generator monad transformer to create+ monadic lists in a manner similar to Python generators. License: BSD3 License-file: LICENSE@@ -18,9 +18,8 @@ Library hs-Source-Dirs: src Extensions:- Build-Depends: base >= 3 && < 5, mtl, MaybeT, List+ Build-Depends: base >= 3 && < 5, mtl, MaybeT, List >= 0.2 Exposed-modules: Control.Monad.DList,- Control.Monad.Consumer, Control.Monad.Generator Ghc-Options: -O2 -Wall
− src/Control/Monad/Consumer.hs
@@ -1,73 +0,0 @@--- | A monad transformer for the [partial] consumption of 'List's.--- The interface closely mimics iterators in languages such as Python.------ It is often nicer to avoid using Consumer and to use--- folds and higher-order functions instead.-module Control.Monad.Consumer (- ConsumerT, evalConsumerT, next, consumeRestM- ) where--import Control.Applicative (Applicative(..))-import Control.Monad (MonadPlus(..), ap)-import Control.Monad.ListT (ListT(..), ListItem(..))-import Control.Monad.Maybe (MaybeT(..))-import Control.Monad.State (StateT, evalStateT, get, put)-import Control.Monad.Trans (MonadTrans(..), MonadIO(..))-import Data.List.Class (List(..))-import Data.Maybe (fromMaybe)---- | A monad tranformer for consuming 'List's.-newtype ConsumerT v m a = ConsumerT { runConsumerT :: StateT (Maybe (ListT m v)) m a }--instance Monad m => Functor (ConsumerT v m) where- fmap f = ConsumerT . fmap f . runConsumerT--instance Monad m => Monad (ConsumerT v m) where- return = ConsumerT . return- fail = ConsumerT . fail- a >>= b = ConsumerT $ runConsumerT a >>= runConsumerT . b--instance Monad m => Applicative (ConsumerT v m) where- pure = return- (<*>) = ap--instance MonadTrans (ConsumerT v) where- lift = ConsumerT . lift--instance MonadIO m => MonadIO (ConsumerT v m) where- liftIO = lift . liftIO---- | Consume a 'ListT'-evalConsumerT :: List l => ConsumerT v (ItemM l) a -> l v -> ItemM l a-evalConsumerT (ConsumerT i) = evalStateT i . Just . toListT---- Consumer no longer has a producer left...-putNoProducer :: List l => StateT (Maybe (l v)) (ItemM l) ()-putNoProducer = put Nothing---- | Consume/get the next value-next :: Monad m => ConsumerT v m (Maybe v)-next =- ConsumerT . runMaybeT $ do- list <- MaybeT get- item <- lift . lift $ runListT list- case item of- Nil -> do- lift putNoProducer- mzero- Cons x xs -> do- putProducer xs- return x- where- putProducer = put . Just---- | Return an instance of the underlying monad that will use the given 'ConsumerT' to consume the remaining values.--- After this action there are no more items to consume (they belong to the given ConsumerT now)-consumeRestM :: Monad m => ConsumerT a m b -> ConsumerT a m (m b)-consumeRestM consume =- ConsumerT $ do- mRest <- get- let rest = fromMaybe mzero mRest- putNoProducer- return $ evalConsumerT consume rest-
src/Control/Monad/DList.hs view
@@ -9,7 +9,7 @@ -- The transformation from a list to a difference list is /O(N)/. module Control.Monad.DList (- DListT (..)+ DListT (..), toListT, joinDListT ) where import Control.Applicative (Applicative(..))@@ -22,6 +22,13 @@ -- | A monadic difference-list newtype DListT m a = DListT { runDListT :: ListT m a -> ListT m a } +toListT :: Monad m => DListT m a -> ListT m a+toListT = (`runDListT` mzero)++joinDListT :: Monad m => m (DListT m a) -> DListT m a+joinDListT action =+ DListT (joinL . (`liftM` action) . flip runDListT)+ instance Monoid (DListT l a) where mempty = DListT id mappend (DListT a) (DListT b) = DListT $ a . b@@ -40,13 +47,6 @@ instance Monad m => MonadPlus (DListT m) where mzero = mempty mplus = mappend--instance Monad m => List (DListT m) where- type ItemM (DListT m) = m- joinL action =- DListT $ \rest -> joinL $- liftM (`runDListT` rest) action- toListT = (`runDListT` mzero) instance MonadTrans DListT where lift = DListT . mappend . lift
src/Control/Monad/Generator.hs view
@@ -1,7 +1,9 @@ -- | A monad transformer for the creation of Lists. -- Similar to Python's generators. ----- > import Data.List.Class (convList)+-- > import Control.Monad.DList (toListT)+-- > import Control.Monad.Identity (Identity(..))+-- > import Data.List.Class (toList) -- > -- > hanoi 0 _ _ _ = mempty -- > hanoi n from to other =@@ -10,7 +12,7 @@ -- > yield (from, to) -- > yields $ hanoi (n-1) other to from -- >--- > > convList (hanoi 3 'A' 'B' 'C') :: [(Char, Char)]+-- > > runIdentity . toList . toListT $ hanoi 3 'A' 'B' 'C' :: [(Char, Char)] -- > [('A','B'),('A','C'),('B','C'),('A','B'),('C','A'),('C','B'),('A','B')] -- @@ -21,9 +23,9 @@ import Control.Applicative (Applicative(..)) import Control.Monad (liftM, ap) import Control.Monad.Cont (Cont (..))-import Control.Monad.DList (DListT)+import Control.Monad.DList (DListT, joinDListT) import Control.Monad.Trans (MonadTrans(..), MonadIO(..))-import Data.List.Class (cons, joinL)+import Data.List.Class (cons) import Data.Monoid (Monoid(..)) -- | A monad transformer to create 'List's.@@ -44,7 +46,7 @@ (<*>) = ap instance MonadTrans (GeneratorT v) where- lift m = GeneratorT . Cont $ joinL . (`liftM` m)+ lift = GeneratorT . Cont . (joinDListT .) . flip liftM instance MonadIO m => MonadIO (GeneratorT v m) where liftIO = lift . liftIO@@ -53,11 +55,14 @@ generate :: Monad m => GeneratorT v m () -> DListT m v generate = ($ const mempty) . runCont . runGeneratorT +mkContNil :: (r -> r) -> Cont r ()+mkContNil = Cont . (. ($ ()))+ -- | /O(1)/, Output a result value yield :: Monad m => v -> GeneratorT v m ()-yield x = GeneratorT . Cont $ cons x . ($ ())+yield = GeneratorT . mkContNil . cons -- | /O(1)/, Output all the values of a 'DListT'. yields :: Monad m => DListT m v -> GeneratorT v m ()-yields xs = GeneratorT . Cont $ mappend xs . ($ ())+yields = GeneratorT . mkContNil . mappend