packages feed

monadlist (empty) → 0.0.1

raw patch · 4 files changed

+466/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Thomas Eding
+
+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 Thomas Eding nor the names of other
+      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 THE COPYRIGHT
+OWNER OR CONTRIBUTORS 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.
+ Setup.lhs view
@@ -0,0 +1,6 @@+#!/usr/bin/runhaskell 
+> module Main where
+> import Distribution.Simple
+> main :: IO ()
+> main = defaultMain
+
+ monadlist.cabal view
@@ -0,0 +1,50 @@+name: monadlist+version: 0.0.1+cabal-version: -any+build-type: Simple+license: BSD3+license-file: LICENSE+copyright:+maintainer: thomasedingcode@gmail.com+build-depends: base >=3 && <5+stability:+homepage:+package-url:+bug-reports:+synopsis: Monadic versions of list functions+description: Monadic versions of list functions seen in Data.List.+category: Control+author: Thomas Eding+tested-with:+data-files:+data-dir: ""+extra-source-files:+extra-tmp-files:+exposed-modules: Control.Monad.ListM+exposed: True+buildable: True+build-tools:+cpp-options:+cc-options:+ld-options:+pkgconfig-depends:+frameworks:+c-sources:+default-language:+other-languages:+default-extensions:+other-extensions:+extensions:+extra-libraries:+extra-lib-dirs:+includes:+install-includes:+include-dirs:+hs-source-dirs: src+other-modules:+ghc-prof-options:+ghc-shared-options:+ghc-options:+hugs-options:+nhc98-options:+jhc-options:
+ src/Control/Monad/ListM.hs view
@@ -0,0 +1,380 @@+-----------------------------------------------------------------------------+--+-- Module      :  Control.Monad.ListM+-- Copyright   :+-- License     :  AllRightsReserved+--+-- Maintainer  :+-- Stability   :+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++module Control.Monad.ListM (+  mapMP+, filterMP+, intersperseM+, foldM1+, joinMap+, joinMapM+, anyM+, allM+, scanM+, mapAccumM+, iterateM+, takeM+, dropM+, splitAtM+, takeWhileM+, dropWhileM+, spanM+, breakM+, elemM+, notElemM+, lookupM+, findM+, partitionM+, elemIndexM+, elemIndicesM+, findIndexM+, findIndicesM+, zipWithM3+, zipWithM4+, zipWithM5+, zipWithM6+, nubM+, nubByM+, deleteM+, deleteByM+, deleteFirstsM+, deleteFirstsByM+, unionM+, unionByM+, intersectM+, intersectByM+, groupM+, groupByM+, sortM+, sortByM+, insertM+, insertByM+, maximumM+, maximumByM+, minimumM+, minimumByM+) where++import qualified Prelude+import Prelude hiding (error, mapM, sequence, and, or)++import Control.Monad hiding (mapM, sequence)+import Data.Foldable (or, and)+import Data.List (zip4, zip5, zip6)+import Data.Maybe (isJust)+import Data.Traversable (Traversable, mapM, sequence)+++infixr 5 !, !!!+++error :: String -> String -> a+error func msg = Prelude.error $ "Control.Monad.ListM." ++ func ++ ": " ++ msg++notM :: (Monad m) => Bool -> m Bool+notM = return . not++eqM :: (Eq a, Monad m) => a -> a -> m Bool+eqM x y = return $ x == y++compareM :: (Ord a, Monad m) => a -> a -> m Ordering+compareM x y = return $ compare x y++(!) :: (MonadPlus p) => a -> p a -> p a+x ! y = return x `mplus` y++(!!!) :: (MonadPlus p) => [a] -> p a -> p a+(!!!) = flip $ foldr (!)++uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)+uncurry3 f (x, y, z) = f x y z++uncurry4 :: (a -> b -> c -> d -> e) -> ((a, b, c, d) -> e)+uncurry4 f (x, y, z, w) = f x y z w++uncurry5 :: (a -> b -> c -> d -> e -> f) -> ((a, b, c, d, e) -> f)+uncurry5 f (x, y, z, w, s) = f x y z w s++uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> ((a, b, c, d, e, f) -> g)+uncurry6 f (x, y, z, w, s, t) = f x y z w s t++mapMP :: (Monad m, MonadPlus p) => (a -> m b) -> [a] -> m (p b)+mapMP _ [] = return mzero+mapMP f (x:xs) = do+  y <- f x+  liftM (y!) $ mapMP f xs++filterMP :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a)+filterMP _ [] = return mzero+filterMP p (x:xs) = do+  bool <- p x+  if bool+    then liftM (x!) $ filterMP p xs+    else filterMP p xs++intersperseM :: (Monad m, MonadPlus p) => m a -> [a] -> m (p a)+intersperseM _ [] = return mzero+intersperseM _ [x] = return $ return x+intersperseM m (x:ys) = do+  z <- m+  liftM ([x, z] !!!) $ intersperseM m ys++intercalateM :: (Monad m, MonadPlus p) => m (p a) -> [p a] -> m (p a)+intercalateM m = liftM join . intersperseM m++foldM1 :: (Monad m) => (a -> a -> m a) -> [a] -> m a+foldM1 _ [] = error "foldM1" "empty list"+foldM1 f (x:xs) = foldM f x xs++joinMap :: (Monad m) => (a -> m b) -> m a -> m b+joinMap f = join . liftM f++joinMapM :: (Monad m, MonadPlus p) => (a -> m (p b)) -> [a] -> m (p b)+joinMapM f = liftM join . mapMP f++anyM :: (Monad m, Traversable t) => (a -> m Bool) -> t a -> m Bool+anyM p = liftM or . mapM p++allM :: (Monad m, Traversable t) => (a -> m Bool) -> t a -> m Bool+allM p = liftM and . mapM p++scanM :: (Monad m, MonadPlus p) => (a -> b -> m a) -> a -> [b] -> m (p a)+scanM _ z [] =  return $ return z+scanM f z (x:xs) = do+  z' <- f z x+  liftM (z!) $ scanM f z' xs++mapAccumM :: (Monad m, MonadPlus p) => (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, p y)+mapAccumM _ z [] = return (z, mzero)+mapAccumM f z (x:xs) = do+  (z', y) <- f z x+  (z'', ys) <- mapAccumM f z' xs+  return (z'', y!ys)++iterateM :: (Monad m, MonadPlus p) => (a -> m a) -> a -> m (p a)+iterateM f x = do+  x' <- f x+  liftM (x!) $ iterateM f x'++takeM :: (Integral i, Monad m, MonadPlus p) => i -> [m a] -> m (p a)+takeM _ [] = return mzero+takeM n (m:ms)+  | n <= 0 = return mzero+  | otherwise = m >>= \x -> liftM (x!) $ takeM (n-1) ms++dropM :: (Integral i, Monad m) => i -> [m a] -> m [a]+dropM _ [] = return []+dropM n (m:ms)+  | n <= 0 = sequence $ m:ms+  | otherwise = m >> dropM (n-1) ms++splitAtM :: (Integral i, Monad m, MonadPlus p) => i -> [m a] -> m (p a, [a])+splitAtM _ [] = return (mzero, [])+splitAtM n (m:ms)+  | n <= 0 = do+      ys <- sequence $ m:ms+      return (mzero, ys)+  | otherwise = do+      x <- m+      (xs, ys) <- splitAtM (n-1) ms+      return (x!xs, ys)++takeWhileM :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a)+takeWhileM _ [] = return mzero+takeWhileM p (x:xs) = do+  bool <- p x+  if bool+    then liftM (x!) $ takeWhileM p xs+    else return mzero++dropWhileM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]+dropWhileM _ [] = return []+dropWhileM p (x:xs) = do+  bool <- p x+  if bool+    then dropWhileM p xs+    else return $ x:xs++spanM :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a, [a])+spanM _ [] = return (mzero, [])+spanM p (x:xs) = do+  bool <- p x+  if bool+    then do+      (ys, zs) <- spanM p xs+      return (x!ys, zs)+    else return (mzero, x:xs)++breakM :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a, [a])+breakM p = spanM $ notM <=< p++elemM :: (Eq a, Monad m) => a -> [a] -> m Bool+elemM x = liftM isJust . elemIndexM x++notElemM :: (Eq a, Monad m) => a -> [a] -> m Bool+notElemM x = notM <=< elemM x++lookupM :: (Eq a, Monad m, MonadPlus p) => a -> [m (a, b)] -> m (p b)+lookupM _ [] = return mzero+lookupM x (m:ms) = do+  (k, v) <- m+  if x == k+    then return $ return v+    else lookupM x ms++findM :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a)+findM _ [] = return mzero+findM p (x:xs) = do+  bool <- p x+  if bool+    then return $ return x+    else findM p xs++partitionM :: (Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p a, [a])+partitionM _ [] = return (mzero, [])+partitionM p (x:xs) = do+  bool <- p x+  if bool+    then do+      (ys, zs) <- partitionM p xs+      return (x!ys, zs)+    else return (mzero, x:xs)++elemIndexM :: (Eq a, Integral i, Monad m, MonadPlus p) => a -> [a] -> m (p i)+elemIndexM x = findIndexM $ eqM x++elemIndicesM :: (Eq a, Integral i, Monad m, MonadPlus p) => a -> [a] -> m (p i)+elemIndicesM x = findIndicesM $ eqM x++findIndexM :: (Integral i, Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p i)+findIndexM p = liftM (liftM fst) . findM (p . snd) . zip [0..]++findIndicesM :: (Integral i, Monad m, MonadPlus p) => (a -> m Bool) -> [a] -> m (p i)+findIndicesM p = liftM (liftM fst) . filterMP (p . snd) . zip [0..]++zipWithM3 :: (Monad m, MonadPlus p) => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m (p d)+zipWithM3 f xs ys = mapMP (uncurry3 f) . zip3 xs ys++zipWithM4 :: (Monad m, MonadPlus p) => (a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> m (p e)+zipWithM4 f xs ys zs = mapMP (uncurry4 f) . zip4 xs ys zs++zipWithM5 :: (Monad m, MonadPlus p) => (a -> b -> c -> d -> e -> m f) -> [a] -> [b] -> [c] -> [d] -> [e] -> m (p f)+zipWithM5 f xs ys zs ws = mapMP (uncurry5 f) . zip5 xs ys zs ws++zipWithM6 :: (Monad m, MonadPlus p) => (a -> b -> c -> d -> e -> f -> m g) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> m (p g)+zipWithM6 f xs ys zs ws ss = mapMP (uncurry6 f) . zip6 xs ys zs ws ss++nubM :: (Eq a, Monad m, MonadPlus p) => [a] -> m (p a)+nubM = nubByM eqM++nubByM :: (Monad m, MonadPlus p) => (a -> a -> m Bool) -> [a] -> m (p a)+nubByM _ [] = return mzero+nubByM eq (x:xs) = liftM (x!) $ filterM (notM <=< eq x) xs >>= nubByM eq++deleteM :: (Eq a, Monad m) => a -> [a] -> m [a]+deleteM = deleteByM eqM++deleteByM :: (Monad m) => (a -> a -> m Bool) -> a -> [a] -> m [a]+deleteByM _ _ [] = return []+deleteByM eq x (y:ys) = do+  bool <- eq x y+  if bool+    then return ys+    else liftM (y:) $ deleteByM eq x ys++deleteFirstsM :: (Eq a, Monad m) => [a] -> [a] -> m [a]+deleteFirstsM = deleteFirstsByM eqM++deleteFirstsByM :: (Monad m) => (a -> a -> m Bool) -> [a] -> [a] -> m [a]+deleteFirstsByM _ xs [] = return xs+deleteFirstsByM eq xs (y:ys) = do+  xs' <- deleteByM eq y xs+  deleteFirstsByM eq xs' ys++unionM :: (Eq a, Monad m) => [a] -> [a] -> m [a]+unionM = unionByM eqM++unionByM :: (Monad m) => (a -> a -> m Bool) -> [a] -> [a] -> m [a]+unionByM eq ys xs = do+  ys' <- nubByM eq ys+  ys'' <- foldM (flip $ deleteByM eq) ys' xs+  return $ xs ++ ys''++intersectM :: (Eq a, Monad m, MonadPlus p) => [a] -> [a] -> m (p a)+intersectM = intersectByM eqM++intersectByM :: (Monad m, MonadPlus p) => (a -> a -> m Bool) -> [a] -> [a] -> m (p a)+intersectByM _ [] _ = return mzero+intersectByM _ _ [] = return mzero+intersectByM eq (x:xs) ys = do+  bool <- anyM (eq x) ys+  if bool+    then liftM (x!) $ intersectByM eq xs ys+    else intersectByM eq xs ys++groupM :: (Eq a, Monad m, MonadPlus p, MonadPlus q) => [a] -> m (p (q a))+groupM = groupByM eqM++groupByM :: (Monad m, MonadPlus p, MonadPlus q) => (a -> a -> m Bool) -> [a] -> m (p (q a))+groupByM _ [] = return mzero+groupByM eq (x:xs) = do+  (ys, zs) <- spanM (eq x) xs+  liftM ((x!ys)!) $ groupByM eq zs++sortM :: (Ord a, Monad m) => [a] -> m [a]+sortM = sortByM compareM++sortByM :: (Monad m) => (a -> a -> m Ordering) -> [a] -> m [a]+sortByM _ [] = return []+sortByM cmp (x:xs) = sortByM cmp xs >>= insertByM cmp x++insertM :: (Ord a, Monad m) => a -> [a] -> m [a]+insertM = insertByM compareM++insertByM :: (Monad m) => (a -> a -> m Ordering) -> a -> [a] -> m [a]+insertByM _ x [] = return [x]+insertByM cmp x (y:ys) = do+  ordering <- cmp x y+  case ordering of+    GT -> liftM (y:) $ insertByM cmp x ys+    _ -> return $ x:y:ys++maximumM :: (Ord a, Monad m) => [a] -> m a+maximumM [] = error "maximumM" "empty list"+maximumM xs = maximumByM compareM xs++maximumByM :: (Monad m) => (a -> a -> m Ordering) -> [a] -> m a+maximumByM _ [] = error "maximumByM" "empty list"+maximumByM cmp xs = foldM1 maxByM xs+  where+    maxByM x y = do+      ordering <- cmp x y+      return $ case ordering of+        GT -> x+        _ -> y++minimumM :: (Ord a, Monad m) => [a] -> m a+minimumM [] = error "minimumM" "empty list"+minimumM xs = minimumByM compareM xs++minimumByM :: (Monad m) => (a -> a -> m Ordering) -> [a] -> m a+minimumByM _ [] = error "minimumByM" "empty list"+minimumByM cmp xs = foldM1 minByM xs+  where+    minByM x y = do+      ordering <- cmp x y+      return $ case ordering of+        GT -> y+        _ -> x+