fmlist 0.5 → 0.6
raw patch · 2 files changed
+60/−47 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.FMList: instance (Applicative f, Monoid m) => Monoid (WrapApp f m)
- Data.FMList: FM :: (forall b. (Monoid b) => (a -> b) -> b) -> FMList a
+ Data.FMList: FM :: (forall m. (Monoid m) => (a -> m) -> m) -> FMList a
- Data.FMList: transform :: (forall b. (Monoid b) => (a -> b) -> (c -> b)) -> FMList c -> FMList a
+ Data.FMList: transform :: (forall m. (Monoid m) => (a -> m) -> (b -> m)) -> FMList b -> FMList a
- Data.FMList: unFM :: FMList a -> forall b. (Monoid b) => (a -> b) -> b
+ Data.FMList: unFM :: FMList a -> forall m. (Monoid m) => (a -> m) -> m
- Data.FMList: unfold :: (Foldable t) => (b -> t (Either b a)) -> b -> FMList a
+ Data.FMList: unfold :: (b -> FMList (Either b a)) -> b -> FMList a
Files
- Data/FMList.hs +59/−46
- fmlist.cabal +1/−1
Data/FMList.hs view
@@ -4,7 +4,7 @@ -- Copyright : (c) Sjoerd Visscher 2009 -- License : BSD-style (see the file LICENSE) ----- Maintainer : sjoerd+-- Maintainer : sjoerd@w3future.com -- Stability : experimental -- Portability : portable --@@ -28,6 +28,7 @@ ----------------------------------------------------------------------------- {-# LANGUAGE RankNTypes #-} + module Data.FMList ( FMList(..)@@ -77,8 +78,9 @@ import Prelude ( (.), ($), ($!), flip, const, id, error- , Maybe(..), maybe, Either(..)- , Bool(..), (||), not+ , Maybe(..), maybe+ , Either(..), either+ , Bool(..), (&&) , Ord(..), Num(..), Int , Show(..), String, (++) )@@ -92,7 +94,7 @@ -- | 'FMList' is a 'foldMap' function wrapped up in a newtype. ---newtype FMList a = FM { unFM :: forall b . Monoid b => (a -> b) -> b }+newtype FMList a = FM { unFM :: forall m . Monoid m => (a -> m) -> m } -- | The function 'transform' transforms a list by changing -- the map function that is passed to 'foldMap'.@@ -115,30 +117,37 @@ -- -- * @= transform (\\f -> foldMap f . g) m@ -- -transform :: (forall b. Monoid b => (a -> b) -> (c -> b)) -> FMList c -> FMList a-transform t l = FM $ \f -> unFM l (t f)+transform :: (forall m. Monoid m => (a -> m) -> (b -> m)) -> FMList b -> FMList a+transform t (FM l) = FM (l . t) --- nil is exported as empty from Applicative+-- shorthand constructors nil :: FMList a-nil = FM $ \_ -> mempty+nil = FM mempty +one :: a -> FMList a+one x = FM ($ x)++(#) :: FMList a -> FMList a -> FMList a+FM l # FM r = FM (l `mappend` r)++-- exported constructors singleton :: a -> FMList a-singleton x = FM $ \f -> f x+singleton = one cons :: a -> FMList a -> FMList a-cons x l = FM $ \f -> f x `mappend` unFM l f+cons x l = one x # l snoc :: FMList a -> a -> FMList a-snoc l x = FM $ \f -> unFM l f `mappend` f x+snoc l x = l # one x pair :: a -> a -> FMList a-pair l r = FM $ \f -> f l `mappend` f r+pair l r = one l # one r append :: FMList a -> FMList a -> FMList a--- append l r = FM $ \f -> unFM l f `mappend` unFM r f-append l r = FM $ unFM l `mappend` unFM r+append = (#) + fromList :: [a] -> FMList a fromList = fromFoldable @@ -146,8 +155,11 @@ fromFoldable l = FM $ flip foldMap l +mhead :: FMList a -> Maybe a+mhead l = getFirst (unFM l (First . Just))+ null :: FMList a -> Bool-null = foldr (\_ _ -> False) True+null = maybe True (const False) . mhead length :: FMList a -> Int length = genericLength@@ -157,7 +169,7 @@ head :: FMList a -> a-head l = getFirst (unFM l (First . Just)) `fromJustOrError` "Data.FMList.head: empty list"+head l = mhead l `fromJustOrError` "Data.FMList.head: empty list" tail :: FMList a -> FMList a tail l = if null l then error "Data.FMList.tail: empty list" else drop (1::Int) l@@ -169,7 +181,7 @@ init l = if null l then error "Data.FMList.init: empty list" else reverse . drop (1::Int) . reverse $ l reverse :: FMList a -> FMList a-reverse l = FM $ \f -> getDual $ unFM l (Dual . f)+reverse l = FM $ getDual . unFM l . (Dual .) flatten :: Foldable t => FMList (t a) -> FMList a@@ -178,27 +190,25 @@ filter :: (a -> Bool) -> FMList a -> FMList a filter p = transform (\f e -> if p e then f e else mempty) -take :: (Ord n, Num n) => n -> FMList a -> FMList a-take n l = FM $ \f -> - foldr (\e r i -> if i > 0 then mappend (f e) (r (i-1)) else mempty) (const mempty) l n -drop :: (Ord n, Num n) => n -> FMList a -> FMList a-drop n l = FM $ \f -> - foldr (\e r i -> if i <= 0 then mappend (f e) (r i) else r (i-1)) (const mempty) l n+-- transform the foldMap to foldr with state.+transformCS :: (forall m. Monoid m => (b -> m) -> a -> (m -> s -> m) -> s -> m) -> s -> FMList a -> FMList b+transformCS t s0 l = FM $ \f -> foldr (\e r -> t f e (\a -> mappend a . r)) mempty l s0 +take :: (Ord n, Num n) => n -> FMList a -> FMList a+take n = transformCS (\f e c i -> if i > 0 then c (f e) (i-1) else mempty) n+ takeWhile :: (a -> Bool) -> FMList a -> FMList a-takeWhile p l = FM $ \f -> - foldr (\e r -> if p e then mappend (f e) r else mempty) mempty l+takeWhile p = transformCS (\f e c _ -> if p e then c (f e) True else mempty) True -dropWhile :: (a -> Bool) -> FMList a -> FMList a-dropWhile p l = FM $ \f -> - foldr (\e r done -> if done || not (p e) then mappend (f e) (r True) else r False) (const mempty) l False+drop :: (Ord n, Num n) => n -> FMList a -> FMList a+drop n = transformCS (\f e c i -> if i <= 0 then c (f e) 0 else c mempty (i-1)) n +dropWhile :: (a -> Bool) -> FMList a -> FMList a+dropWhile p = transformCS (\f e c ok -> if ok && p e then c mempty True else c (f e) False) True zipWith :: (a -> b -> c) -> FMList a -> FMList b -> FMList c-zipWith t l1 l2 = FM $ \f -> - foldr (\e1 r r2 -> - foldr (\e2 _ -> mappend (f (t e1 e2)) (r (drop (1::Int) r2))) mempty r2) (const mempty) l1 l2+zipWith t = transformCS (\f e2 c r1 -> foldr (\e1 _ -> c (f (t e1 e2)) (drop (1::Int) r1)) mempty r1) zip :: FMList a -> FMList b -> FMList (a,b) zip = zipWith (,)@@ -225,8 +235,7 @@ unfoldr g = unfold (maybe empty (\(a, b) -> Right a `pair` Left b) . g) -- | 'unfold' builds a list from a seed value.--- The function takes the seed and returns an 'FMList' --- (or any other 'Foldable' instance) of values.+-- The function takes the seed and returns an 'FMList' of values. -- If the value is 'Right' @a@, then @a@ is appended to the result, and if the -- value is 'Left' @b@, then @b@ is used as seed value in a recursive call. --@@ -235,10 +244,8 @@ -- > *> unfold (\b -> if b == 0 then empty else Left (b-1) `pair` Right b) 10 -- > fromList [1,2,3,4,5,6,7,8,9,10] ---unfold :: Foldable t => (b -> t (Either b a)) -> b -> FMList a-unfold g b = FM $ \f -> foldMap (u f) (g b) where- u f (Left b) = foldMap (u f) (g b)- u f (Right a) = f a+unfold :: (b -> FMList (Either b a)) -> b -> FMList a+unfold g = transform (\f -> either (foldMap f . unfold g) f) . g instance Functor FMList where@@ -247,32 +254,38 @@ instance Foldable FMList where foldMap = flip unFM -instance Traversable FMList where- traverse f = foldr cons_f (pure empty) where cons_f x ys = cons <$> f x <*> ys- instance Monad FMList where- return = singleton+ return = one m >>= g = transform (\f -> foldMap f . g) m instance Applicative FMList where- pure = return+ pure = one gs <*> xs = transform (\f g -> unFM xs (f . g)) gs instance Monoid (FMList a) where mempty = nil- mappend = append+ mappend = (#) instance MonadPlus FMList where mzero = nil- mplus = append+ mplus = (#) instance Alternative FMList where empty = nil- (<|>) = append+ (<|>) = (#) instance Show a => Show (FMList a) where show l = "fromList " ++ (show $! toList l) - ++newtype WrapApp f m = WrapApp { unWrapApp :: f m }+instance (Applicative f, Monoid m) => Monoid (WrapApp f m) where+ mempty = WrapApp $ pure mempty+ mappend (WrapApp a) (WrapApp b) = WrapApp $ mappend <$> a <*> b++instance Traversable FMList where+ traverse f = unWrapApp . foldMap one_f where one_f x = WrapApp $ one <$> f x++ fromJustOrError :: Maybe a -> String -> a fromJustOrError ma e = maybe (error e) id ma
fmlist.cabal view
@@ -1,5 +1,5 @@ name: fmlist-version: 0.5+version: 0.6 synopsis: FoldMap lists description: FoldMap lists are lists represented by their foldMap function.