list-t 0.2.3 → 0.2.4
raw patch · 3 files changed
+84/−10 lines, 3 filesdep ~HTF
Dependency ranges changed: HTF
Files
- executables/APITests.hs +4/−0
- library/ListT.hs +77/−7
- list-t.cabal +3/−3
executables/APITests.hs view
@@ -124,6 +124,10 @@ assertEqual [3, 4] =<< do toList $ L.drop 2 $ L.fromFoldable [1 .. 4] +test_slice =+ assertEqual ["abc", "def", "gh"] =<< do+ toList $ L.slice (fromJust $ L.positive 3) $ L.fromFoldable ("abcdefgh" :: [Char])+ toList :: Monad m => L.ListT m a -> m [a] toList = L.toList
library/ListT.hs view
@@ -11,7 +11,9 @@ null, fold, toList,+ toReverseList, traverse_,+ splitAt, -- * Construction utilities fromFoldable, unfold,@@ -22,13 +24,18 @@ -- without actually traversing the stream. -- They only get applied with a single traversal, -- which happens at the execution.+ Transformation, traverse, take, drop,+ slice,+ -- * Positive numbers+ Positive,+ positive, ) where -import BasePrelude hiding (toList, yield, fold, traverse, head, tail, take, drop, repeat, null, traverse_)+import BasePrelude hiding (toList, yield, fold, traverse, head, tail, take, drop, repeat, null, traverse_, splitAt) import Control.Monad.Morph import Control.Monad.IO.Class import Control.Monad.Trans.Class@@ -196,13 +203,36 @@ liftM ($ []) . fold (\f e -> return $ f . (e :)) id -- |+-- Execute, folding to a list in a reverse order.+-- Performs more efficiently than 'toList'.+{-# INLINABLE toReverseList #-}+toReverseList :: (Monad m, ListTrans t) => t m a -> m [a]+toReverseList =+ ListT.fold (\l -> return . (:l)) []++-- | -- Execute, traversing the stream with a side effect in the inner monad. {-# INLINABLE traverse_ #-} traverse_ :: (Monad m, ListTrans t) => (a -> m ()) -> t m a -> m () traverse_ f = fold (const f) () +-- |+-- Execute, consuming a list of the specified length and returning the remainder stream.+{-# INLINABLE splitAt #-}+splitAt :: (Monad m, ListTrans t, MonadPlus (t m)) => Int -> t m a -> m ([a], t m a)+splitAt =+ \case+ n | n > 0 -> \l ->+ uncons l >>= \case+ Nothing -> return ([], mzero)+ Just (h, t) -> do+ (r1, r2) <- splitAt (pred n) t+ return (h : r1, r2)+ _ -> \l -> + return ([], l) + -- * Construction ------------------------- @@ -232,20 +262,31 @@ ------------------------- -- |--- A transformation,+-- A transformation function on a list transformer.+-- It may update the structure or the result type, +-- but the type of the transformer remains the same.+-- +-- Since it's merely just a function,+-- you can run it by passing a list transformer as an argument.+type Transformation m a b = + forall t. (Monad m, ListMonad (t m), ListTrans t) =>+ t m a -> t m b++-- |+-- Produce a transformation, -- which traverses the stream with an action in the inner monad. {-# INLINABLE traverse #-}-traverse :: (Monad m, ListMonad (t m), ListTrans t) => (a -> m b) -> t m a -> t m b+traverse :: (a -> m b) -> Transformation m a b traverse f s = lift (uncons s) >>= mapM (\(h, t) -> lift (f h) >>= \h' -> cons h' (traverse f t)) >>= maybe mzero return -- |--- A trasformation, +-- Produce a transformation, -- reproducing the behaviour of @Data.List.'Data.List.take'@. {-# INLINABLE take #-}-take :: (Monad m, ListMonad (t m), ListTrans t) => Int -> t m a -> t m a+take :: Int -> Transformation m a a take = \case n | n > 0 -> \t ->@@ -257,10 +298,10 @@ const $ mzero -- |--- A trasformation, +-- Produce a transformation, -- reproducing the behaviour of @Data.List.'Data.List.drop'@. {-# INLINABLE drop #-}-drop :: (Monad m, MonadPlus (t m), ListTrans t) => Int -> t m a -> t m a+drop :: Int -> Transformation m a a drop = \case n | n > 0 ->@@ -268,5 +309,34 @@ _ -> id +-- |+-- Produce a transformation,+-- which slices a list into chunks of the specified length.+{-# INLINABLE slice #-}+slice :: Positive Int -> Transformation m a [a]+slice n l = + do+ (h, t) <- lift $ splitAt (case n of Positive n -> n) l+ case h of+ [] -> mzero+ _ -> cons h (slice n t) ++-- * Positive numbers+-------------------------++-- |+-- A newtype wrapper around a number,+-- which ensures that it is greater than zero.+newtype Positive n = + Positive n+ deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)++-- |+-- A smart constructor for positive numbers.+positive :: (Ord n, Num n) => n -> Maybe (Positive n)+positive =+ \case+ n | n > 0 -> Just $ Positive n+ _ -> Nothing
list-t.cabal view
@@ -1,12 +1,12 @@ name: list-t version:- 0.2.3+ 0.2.4 synopsis: ListT done right description: A correct implementation of the list monad-transformer.- Useful for streaming of mutable datastructures.+ Useful for basic streaming. category: Data Structures, Control, Monad, Data homepage:@@ -63,7 +63,7 @@ APITests.hs build-depends: list-t,- HTF == 0.11.*,+ HTF == 0.12.*, mtl-prelude == 0.1.*, base-prelude >= 0.1.3 && < 0.2 default-extensions: