monadplus 1.2 → 1.3
raw patch · 3 files changed
+226/−29 lines, 3 files
Files
- monadplus.cabal +6/−4
- src/Control/Applicative/Alternative.hs +77/−0
- src/Control/Monad/Plus.hs +143/−25
monadplus.cabal view
@@ -1,12 +1,12 @@ name: monadplus-version: 1.2-cabal-version: >= 1.6+version: 1.3+cabal-version: >= 1.10 author: Hans Hoglund maintainer: Hans Hoglund <hans@hanshoglund.se> license: BSD3 license-file: COPYING-synopsis: Filtering and folding over arbitrary MonadPlus instances.+synopsis: Haskell98 partial maps and filters over MonadPlus. category: Control tested-with: GHC build-type: Simple@@ -21,10 +21,12 @@ type: git location: git://github.com/hanshoglund/monadplus.git -library +library+ default-language: Haskell98 build-depends: base >= 4 && < 5 hs-source-dirs: src exposed-modules:+ Control.Applicative.Alternative Control.Monad.Plus
+ src/Control/Applicative/Alternative.hs view
@@ -0,0 +1,77 @@++-------------------------------------------------------------------------------------+-- |+-- Copyright : (c) Hans Hoglund 2012+--+-- License : BSD-style+--+-- Maintainer : hans@hanshoglund.se+-- Stability : experimental+-- Portability : non-portable (TF,GNTD)+--+-- Partial maps and filters over 'Alternative' instances.+--+-- This is considerably weaker than 'MonadPlus', as we have no possibility of removing+-- intermediate structure, as in 'mcatMaybes'.+--+-------------------------------------------------------------------------------------++module Control.Applicative.Alternative (+ -- * Basics+ module Control.Applicative,+ asum,+ asum', + + -- * Constructing+ afold,+ afromList,+ afromMaybe,++ -- -- * Filtering+ -- afilter',+ -- apartition,+ -- + -- -- ** Special filters+ -- ascatter,+ -- ascatter',+ -- acatMaybes,+ -- alefts,+ -- arights,+ -- apartitionEithers,+ -- + -- -- * Special maps+ -- amapMaybe,+ -- aconcatMap,+ ) where++import Control.Applicative+import Data.Foldable (Foldable(..), toList, asum)+import qualified Data.Foldable as Foldable++-- |+-- This generalizes the list-based 'concat' function. +-- +asum' :: (Alternative f, Foldable t) => t (f a) -> f a+asum' = Foldable.asum++-- | +-- Fold a value into an arbitrary 'MonadPlus' type.+-- +-- This function generalizes the 'toList' function.+-- +afold :: (Alternative f, Foldable t) => t a -> f a+afold = afromList . Foldable.toList++-- | +-- This function generalizes the 'listToMaybe' function.+-- +afromList :: Alternative f => [a] -> f a+afromList = asum . map pure++-- | +-- Translate maybe to an arbitrary 'Alternative' type.+-- +-- This function generalizes the 'maybeToList' function.+-- +afromMaybe :: Alternative f => Maybe a -> f a+afromMaybe = maybe empty pure
src/Control/Monad/Plus.hs view
@@ -1,74 +1,192 @@ +-------------------------------------------------------------------------------------+-- |+-- Copyright : (c) Hans Hoglund 2012+--+-- License : BSD-style+--+-- Maintainer : hans@hanshoglund.se+-- Stability : experimental+-- Portability : non-portable (TF,GNTD)+--+-- Partial maps and filters over 'MonadPlus' instances.+--+-- This is especially useful for sequential structures such as event lists, tracks etc.+--+-- Inspired by the Conal Elliott's blog post:+--+-- * <http://conal.net/blog/posts/a-handy-generalized-filter>+--+-------------------------------------------------------------------------------------+ module Control.Monad.Plus (- MonadPlus(..),+ -- * Basics+ module Control.Monad, msum,- mfilter,- mremove,- mpartition,+ msum', + + -- * Constructing+ mfold,+ mfromList, mfromMaybe,++ -- * Filtering+ mfilter',+ mpartition,++ -- ** Special filters+ mscatter,+ mscatter', mcatMaybes,+ mlefts,+ mrights,+ mpartitionEithers,++ -- * Special maps mmapMaybe,+ mconcatMap, ) where import Control.Monad+import Data.List (partition)+import Data.Maybe (listToMaybe, maybeToList, catMaybes, mapMaybe)+import Data.Either (lefts, rights, partitionEithers)+import Data.Foldable (Foldable(..), toList)+import qualified Data.Foldable as Foldable +-- |+-- This generalizes the list-based 'concat' function. +-- +msum' :: (MonadPlus m, Foldable t) => t (m a) -> m a+msum' = Foldable.msum+ -- | --- Generalizes the 'listToMaybe' function.+-- Fold a value into an arbitrary 'MonadPlus' type. -- +-- This function generalizes the 'toList' function.+-- +mfold :: (MonadPlus m, Foldable t) => t a -> m a+mfold = mfromList . Foldable.toList++-- | +-- Translate a list to an arbitrary 'MonadPlus' type.+--+-- This function generalizes the 'listToMaybe' function.+-- mfromList :: MonadPlus m => [a] -> m a mfromList = msum . map return -- | --- Generalizes the 'remove' function.+-- Translate maybe to an arbitrary 'MonadPlus' type. -- -mremove :: MonadPlus m => (a -> Bool) -> m a -> m a-mremove p = mfilter (not . p)+-- This function generalizes the 'maybeToList' function.+-- +mfromMaybe :: MonadPlus m => Maybe a -> m a+mfromMaybe = maybe mzero return -- | --- Generalizes the 'partition' function.+-- 'mfilter'', applied to a predicate and a container, returns the container of+-- those elements that satisfy the predicate; i.e.,+--+-- > filter p xs = [ x | x <- xs, p x]+--+-- This function generalizes the 'filter' function.+-- (Identical to 'mfilter', it is just here for documentation purposes). -- +mfilter' :: MonadPlus m => (a -> Bool) -> m a -> m a+mfilter' = mfilter++-- | +-- The 'partition' function takes a predicate a list and returns+-- the pair of lists of elements which do and do not satisfy the+-- predicate, respectively; i.e.,+--+-- > partition p xs == (filter p xs, filter (not . p) xs)+--+-- This function generalizes the 'partition' function.+-- mpartition :: MonadPlus m => (a -> Bool) -> m a -> (m a, m a)-mpartition p a = (mfilter p a, mremove p a)+mpartition p a = (mfilter p a, mfilter (not . p) a) -- | -- Pass through @Just@ occurrences.--- Generalizes the 'catMaybes' function. -- +-- This function generalizes the 'catMaybes' function.+-- mcatMaybes :: MonadPlus m => m (Maybe a) -> m a-mcatMaybes = (>>= maybe mzero return)--{-- mcatMaybes a = - a >>= maybe mzero return--}+mcatMaybes = (>>= mfromMaybe) -- | --- Translate maybe to an arbitrary 'MonadPlus' type.--- Generalizes the 'maybeToList' function.+-- Pass through @Just@ occurrences. -- -mfromMaybe :: MonadPlus m => Maybe a -> m a-mfromMaybe = maybe mzero return+-- This function generalizes the 'catMaybes' function.+-- +mscatter :: MonadPlus m => m [b] -> m b+mscatter = (>>= mfromList) -- | --- Modify or discard a value.--- Generalizes the 'mapMaybe' function.+-- Pass through @Just@ occurrences. -- -mmapMaybe :: MonadPlus m => (a -> Maybe b) -> m a -> m b-mmapMaybe f = mcatMaybes . liftM f+-- This function generalizes the 'catMaybes' function.+-- +mscatter' :: (MonadPlus m, Foldable t) => m (t b) -> m b+mscatter' = (>>= mfromList . toList) +-- | +-- Pass through @Left@ occurrences.+-- +-- This function generalizes the 'lefts' function.+-- mlefts :: MonadPlus m => m (Either a b) -> m a mlefts = mcatMaybes . liftM l where l (Left a) = Just a l (Right a) = Nothing +-- | +-- Pass through @Right@ occurrences.+-- +-- This function generalizes the 'rights' function.+-- mrights :: MonadPlus m => m (Either a b) -> m b mrights = mcatMaybes . liftM r where r (Left a) = Nothing r (Right a) = Just a +-- | +-- Separate @Left@ and @Right@ occurances.+-- +-- This function generalizes the 'partitionEithers' function.+-- mpartitionEithers :: MonadPlus m => m (Either a b) -> (m a, m b) mpartitionEithers a = (mlefts a, mrights a)+++++-- | +-- Modify or discard a value.+-- +-- This function generalizes the 'mapMaybe' function.+-- +mmapMaybe :: MonadPlus m => (a -> Maybe b) -> m a -> m b+mmapMaybe f = mcatMaybes . liftM f++-- | +-- Modify and return a number of values.+-- +-- This function generalizes the 'concatMap' function.+-- +mconcatMap :: MonadPlus m => (a -> [b]) -> m a -> m b+mconcatMap f = mscatter . liftM f++{-+mmapLefts :: MonadPlus m => (a -> Either b c) -> m a -> m b+mmapLefts f = mlefts . liftM f++mmapRights :: MonadPlus m => (a -> Either c b) -> m a -> m b+mmapRights f = mrights . liftM f+-}