list-transformer 1.0.6 → 1.0.7
raw patch · 2 files changed
+78/−9 lines, 2 files
Files
- list-transformer.cabal +1/−1
- src/List/Transformer.hs +77/−8
list-transformer.cabal view
@@ -1,5 +1,5 @@ name: list-transformer-version: 1.0.6+version: 1.0.7 synopsis: List monad transformer description: This library provides a list monad transformer that enriches lists with effects and streams efficiently in
src/List/Transformer.hs view
@@ -1,10 +1,11 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-} {-| The `ListT` type is like a list that lets you interleave effects between each element of the list. The type's definition is very short:@@ -185,6 +186,7 @@ , select , take , drop+ , dropWhile , takeWhile , unfold , zip@@ -192,6 +194,9 @@ -- * Step , Step(..) + -- * Alternative instances+ , ZipListT(..)+ -- * Re-exports , MonadTrans(..) , MonadIO(..)@@ -216,7 +221,7 @@ import Control.Monad.Reader.Class (MonadReader(..)) import Control.Monad.Trans (MonadTrans(..), MonadIO(..)) import Data.Semigroup (Semigroup(..))-import Prelude hiding (drop, pred, take, takeWhile, zip)+import Prelude hiding (drop, dropWhile, pred, take, takeWhile, zip) import qualified Data.Foldable @@ -495,6 +500,27 @@ Cons _ l' -> next (drop (n-1) l') Nil -> return Nil) +-- | @dropWhile pred xs@ drops elements from the head of @xs@ if they+-- satisfy the predicate, but still runs their effects.+--+-- >>> let list xs = do x <- select xs; liftIO (print (show x)); return x+-- >>> let sum = fold (+) 0 id+-- >>> sum (dropWhile even (list [2,4,5,7,8]))+-- "2"+-- "4"+-- "5"+-- "7"+-- "8"+-- 20+dropWhile :: Monad m => (a -> Bool) -> ListT m a -> ListT m a+dropWhile pred l = ListT (do+ n <- next l+ case n of+ Cons x l'+ | pred x -> next (dropWhile pred l')+ | otherwise -> return (Cons x l')+ Nil -> return Nil )+ -- | @takeWhile pred xs@ takes elements from @xs@ until the predicate @pred@ fails -- -- >>> let list xs = do x <- select xs; liftIO (print (show x)); return x@@ -562,3 +588,46 @@ instance Monad m => Functor (Step m) where fmap _ Nil = Nil fmap k (Cons x l) = Cons (k x) (fmap k l)++-- | Similar to 'ZipList' in /base/: a newtype wrapper over 'ListT' that+-- overrides its normal 'Applicative' instance (combine every combination)+-- with one that "zips" outputs together one at a time.+--+-- >>> let xs = do x <- select [1,2,3,4]; liftIO (print x)+-- >>> let ys = do y <- select [5,6]; liftIO (print y)+-- >>> runListT (xs *> ys)+-- 1+-- 5+-- 6+-- 2+-- 5+-- 6+-- 3+-- 5+-- 6+-- 4+-- 5+-- 6+-- >>> runListT (getZipListT (ZipListT xs *> ZipListT ys))+-- 1+-- 5+-- 2+-- 6+-- 3+--+-- Note that the final "3" is printed even though it isn't paired with+-- anything.+--+-- While this can be used to do zipping, it is usually more convenient to+-- just use 'zip'. This is more useful if you are working with a function+-- that expects "an Applicative instance", written to be polymorphic over+-- all Applicatives.+newtype ZipListT m a = ZipListT { getZipListT :: ListT m a }+ deriving (Functor, Alternative, Foldable, Traversable, MonadTrans, Floating, Fractional, Num, Semigroup, Monoid)++instance Monad m => Applicative (ZipListT m) where+ pure x = ZipListT go+ where+ go = ListT (pure (Cons x go))+ ZipListT fs <*> ZipListT xs = ZipListT (fmap (uncurry ($)) (zip fs xs))+