monadplus-1.4.2/0000755000000000000000000000000012173454754011722 5ustar0000000000000000monadplus-1.4.2/COPYING0000644000000000000000000000273612173454754012765 0ustar0000000000000000 Copyright (c) 2013, Hans Höglund All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. monadplus-1.4.2/monadplus.cabal0000644000000000000000000000154612173454754014716 0ustar0000000000000000 name: monadplus version: 1.4.2 cabal-version: >= 1.10 author: Hans Hoglund maintainer: Hans Hoglund license: BSD3 license-file: COPYING synopsis: Haskell98 partial maps and filters over MonadPlus. category: Control tested-with: GHC build-type: Simple description: Filtering and folding over arbitrary `MonadPlus` instances. This package generalizes many common stream operations such as `filter`, `catMaybes` etc. source-repository head type: git location: git://github.com/hanshoglund/monadplus.git library default-language: Haskell98 build-depends: base >= 4 && < 5 hs-source-dirs: src exposed-modules: Control.Applicative.Alternative Control.Monad.Plus monadplus-1.4.2/Setup.lhs0000644000000000000000000000011512173454754013527 0ustar0000000000000000#! /usr/bin/env runhaskell > import Distribution.Simple > main = defaultMainmonadplus-1.4.2/src/0000755000000000000000000000000012173454754012511 5ustar0000000000000000monadplus-1.4.2/src/Control/0000755000000000000000000000000012173454754014131 5ustar0000000000000000monadplus-1.4.2/src/Control/Applicative/0000755000000000000000000000000012173454754016372 5ustar0000000000000000monadplus-1.4.2/src/Control/Applicative/Alternative.hs0000644000000000000000000000264312173454754021211 0ustar0000000000000000 ------------------------------------------------------------------------------------- -- | -- 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, Foldable.asum, -- * Constructing afold, afromList, afromMaybe, ) where import Control.Applicative import Data.Foldable (Foldable(..)) import qualified Data.Foldable as Foldable -- | -- 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 = Foldable.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 monadplus-1.4.2/src/Control/Monad/0000755000000000000000000000000012173454754015167 5ustar0000000000000000monadplus-1.4.2/src/Control/Monad/Plus.hs0000644000000000000000000001473012173454754016453 0ustar0000000000000000 {-# LANGUAGE DeriveFunctor, DeriveFoldable, GeneralizedNewtypeDeriving #-} ------------------------------------------------------------------------------------- -- | -- 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. 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 following blog post: -- -- * -- ------------------------------------------------------------------------------------- module Control.Monad.Plus ( -- * Basics module Control.Monad, Monad.msum, msum', -- * Constructing mfold, mfromList, mfromMaybe, mreturn, -- * Filtering -- mfilter, mpartition, -- ** Special filters mscatter, mscatter', mcatMaybes, mlefts, mrights, mpartitionEithers, -- * Special maps mmapMaybe, mconcatMap, mconcatMap', -- * Utility Partial(..), partial, predicate, always, never, ) where import Control.Monad hiding (msum) import Control.Applicative import Data.Monoid import Data.List (partition) 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 -- | -- This generalizes the list-based 'concat' function. -- msum' :: (MonadPlus m, Foldable t) => t (m a) -> m a msum' = Foldable.msum -- | -- 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 = Monad.msum . map return -- | -- Translate maybe to an arbitrary 'MonadPlus' type. -- -- This function generalizes the 'maybeToList' function. -- mfromMaybe :: MonadPlus m => Maybe a -> m a mfromMaybe = maybe mzero return -- | -- Convert a partial function to a function returning an arbitrary -- 'MonadPlus' type. -- mreturn :: MonadPlus m => (a -> Maybe b) -> a -> m b mreturn f = mfromMaybe . f -- | -- 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, mfilter (not . p) a) -- | -- Pass through @Just@ elements. -- -- This function generalizes the 'catMaybes' function. -- mcatMaybes :: MonadPlus m => m (Maybe a) -> m a mcatMaybes = (>>= mfromMaybe) -- | -- Join list elements together. -- -- This function generalizes the 'catMaybes' function. -- mscatter :: MonadPlus m => m [b] -> m b mscatter = (>>= mfromList) -- | -- Join foldable elements together. -- -- This function generalizes the 'catMaybes' function. -- mscatter' :: (MonadPlus m, Foldable t) => m (t b) -> m b mscatter' = (>>= mfold) -- | -- Pass through @Left@ elements. -- -- 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@ elements. -- -- 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@ elements. -- -- 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, discard or spawn values. -- -- This function generalizes the 'concatMap' function. -- mconcatMap :: MonadPlus m => (a -> [b]) -> m a -> m b mconcatMap f = mscatter . liftM f -- | -- Modify, discard or spawn values. -- -- This function generalizes the 'concatMap' function. -- mconcatMap' :: (MonadPlus m, Foldable t) => (a -> t b) -> m a -> m b mconcatMap' f = mscatter' . 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 -> do { x <- f r; getPartial (k x) r } -- f >>= k = (join' . fmap k) f -- where -- join' g = Partial $ \x -> do { h <- getPartial g x; getPartial h x } 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