monadplus 1.3 → 1.4
raw patch · 3 files changed
+92/−56 lines, 3 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Applicative.Alternative: asum' :: (Alternative f, Foldable t) => t (f a) -> f a
- Control.Monad.Plus: mfilter' :: MonadPlus m => (a -> Bool) -> m a -> m a
+ Control.Monad.Plus: Partial :: (a -> Maybe b) -> Partial a b
+ Control.Monad.Plus: always :: (a -> b) -> a -> Maybe b
+ Control.Monad.Plus: getPartial :: Partial a b -> a -> Maybe b
+ Control.Monad.Plus: instance Alternative (Partial r)
+ Control.Monad.Plus: instance Applicative (Partial r)
+ Control.Monad.Plus: instance Functor (Partial r)
+ Control.Monad.Plus: instance Monad (Partial r)
+ Control.Monad.Plus: instance MonadPlus (Partial r)
+ Control.Monad.Plus: instance Monoid (Partial a b)
+ Control.Monad.Plus: never :: a -> Maybe c
+ Control.Monad.Plus: newtype Partial a b
+ Control.Monad.Plus: partial :: (a -> Bool) -> a -> Maybe a
+ Control.Monad.Plus: predicate :: (a -> Maybe a) -> a -> Bool
Files
- monadplus.cabal +1/−1
- src/Control/Applicative/Alternative.hs +5/−26
- src/Control/Monad/Plus.hs +86/−29
monadplus.cabal view
@@ -1,6 +1,6 @@ name: monadplus-version: 1.3+version: 1.4 cabal-version: >= 1.10 author: Hans Hoglund maintainer: Hans Hoglund <hans@hanshoglund.se>
src/Control/Applicative/Alternative.hs view
@@ -19,40 +19,18 @@ module Control.Applicative.Alternative ( -- * Basics module Control.Applicative,- asum,- asum', + Foldable.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+import Data.Foldable (Foldable(..)) --- |--- This generalizes the list-based 'concat' function. --- -asum' :: (Alternative f, Foldable t) => t (f a) -> f a-asum' = Foldable.asum+import qualified Data.Foldable as Foldable -- | -- Fold a value into an arbitrary 'MonadPlus' type.@@ -66,7 +44,7 @@ -- This function generalizes the 'listToMaybe' function. -- afromList :: Alternative f => [a] -> f a-afromList = asum . map pure+afromList = Foldable.asum . map pure -- | -- Translate maybe to an arbitrary 'Alternative' type.@@ -75,3 +53,4 @@ -- afromMaybe :: Alternative f => Maybe a -> f a afromMaybe = maybe empty pure +
src/Control/Monad/Plus.hs view
@@ -1,4 +1,9 @@ +{-# LANGUAGE DeriveFunctor, DeriveFoldable, GeneralizedNewtypeDeriving,++ TypeSynonymInstances+ #-}+ ------------------------------------------------------------------------------------- -- | -- Copyright : (c) Hans Hoglund 2012@@ -9,11 +14,13 @@ -- Stability : experimental -- Portability : non-portable (TF,GNTD) ----- Partial maps and filters over 'MonadPlus' instances.+-- Partial maps and filters over 'MonadPlus' instances. The basic idea here is that+-- the monad interface together with the monoidal structure of 'MonadPlus' is enough+-- to implement partial maps and filters (i.e. 'mmapMaybe' and 'mfilter'). -- -- This is especially useful for sequential structures such as event lists, tracks etc. ----- Inspired by the Conal Elliott's blog post:+-- Inspired by the following blog post: -- -- * <http://conal.net/blog/posts/a-handy-generalized-filter> --@@ -22,7 +29,7 @@ module Control.Monad.Plus ( -- * Basics module Control.Monad,- msum,+ Monad.msum, msum', -- * Constructing@@ -31,7 +38,7 @@ mfromMaybe, -- * Filtering- mfilter',+ -- mfilter, mpartition, -- ** Special filters@@ -45,13 +52,23 @@ -- * Special maps mmapMaybe, mconcatMap,+ + -- * Utility+ Partial(..),+ partial,+ predicate,+ always,+ never, ) where -import Control.Monad+import Control.Monad hiding (msum)+import Control.Applicative+import Data.Monoid import Data.List (partition)-import Data.Maybe (listToMaybe, maybeToList, catMaybes, mapMaybe)+import Data.Maybe (listToMaybe, maybeToList, catMaybes, mapMaybe, fromMaybe) import Data.Either (lefts, rights, partitionEithers) import Data.Foldable (Foldable(..), toList)+import qualified Control.Monad as Monad import qualified Data.Foldable as Foldable -- |@@ -74,7 +91,7 @@ -- This function generalizes the 'listToMaybe' function. -- mfromList :: MonadPlus m => [a] -> m a-mfromList = msum . map return+mfromList = Monad.msum . map return -- | -- Translate maybe to an arbitrary 'MonadPlus' type.@@ -85,18 +102,6 @@ mfromMaybe = maybe mzero return -- | --- '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.,@@ -109,7 +114,7 @@ mpartition p a = (mfilter p a, mfilter (not . p) a) -- | --- Pass through @Just@ occurrences.+-- Pass through @Just@ elements. -- -- This function generalizes the 'catMaybes' function. -- @@ -117,7 +122,7 @@ mcatMaybes = (>>= mfromMaybe) -- | --- Pass through @Just@ occurrences.+-- Join list elements together. -- -- This function generalizes the 'catMaybes' function. -- @@ -125,15 +130,15 @@ mscatter = (>>= mfromList) -- | --- Pass through @Just@ occurrences.+-- Join foldable elements together. -- -- This function generalizes the 'catMaybes' function. -- mscatter' :: (MonadPlus m, Foldable t) => m (t b) -> m b-mscatter' = (>>= mfromList . toList)+mscatter' = (>>= mfold) -- | --- Pass through @Left@ occurrences.+-- Pass through @Left@ elements. -- -- This function generalizes the 'lefts' function. -- @@ -144,7 +149,7 @@ l (Right a) = Nothing -- | --- Pass through @Right@ occurrences.+-- Pass through @Right@ elements. -- -- This function generalizes the 'rights' function. -- @@ -155,7 +160,7 @@ r (Right a) = Just a -- | --- Separate @Left@ and @Right@ occurances.+-- Separate @Left@ and @Right@ elements. -- -- This function generalizes the 'partitionEithers' function. -- @@ -163,8 +168,6 @@ mpartitionEithers a = (mlefts a, mrights a) -- -- | -- Modify or discard a value. -- @@ -174,7 +177,7 @@ mmapMaybe f = mcatMaybes . liftM f -- | --- Modify and return a number of values.+-- Modify, discard or spawn values. -- -- This function generalizes the 'concatMap' function. -- @@ -187,6 +190,60 @@ mmapRights :: MonadPlus m => (a -> Either c b) -> m a -> m b mmapRights f = mrights . liftM f+ -} +-- |+-- Convert a predicate to a partial function.+--+partial :: (a -> Bool) -> a -> Maybe a+partial p x = if p x then Just x else Nothing +-- |+-- Convert a partial function to a predicate.+--+predicate :: (a -> Maybe a) -> a -> Bool+predicate f x = case f x of+ Just _ -> True+ Nothing -> False++-- |+-- Convert a total function to a partial function.+-- +always :: (a -> b) -> a -> Maybe b+always f = Just . f++-- |+-- Make a partial function that always rejects its input.+-- +never :: a -> Maybe c+never = const Nothing++-- |+-- Wrapper for partial functions with 'MonadPlus' instance.+--+newtype Partial a b = Partial { getPartial :: a -> Maybe b }+ +instance Functor (Partial r) where+ fmap f (Partial g) = Partial (fmap f . g)++instance Monad (Partial r) where+ return x = Partial (\_ -> Just x)+ Partial f >>= k = Partial $ \r -> f r >>= \x -> getPartial (k x) r++instance MonadPlus (Partial r) where+ mzero = Partial (const Nothing)+ Partial f `mplus` Partial g = Partial $ \x -> f x `mplus` g x++instance Applicative (Partial r) where+ pure x = Partial (\_ -> Just x)+ Partial f <*> Partial g = Partial $ \x -> f x <*> g x++instance Alternative (Partial r) where+ empty = Partial (const Nothing)+ Partial f <|> Partial g = Partial $ \x -> f x <|> g x++instance Monoid (Partial a b) where+ mempty = mzero+ mappend = mplus+