packages feed

List 0.1 → 0.2

raw patch · 3 files changed

+88/−126 lines, 3 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Control.Monad.ListT: Cons :: a -> l a -> ListItem l a
- Control.Monad.ListT: ListT :: m (ListItem (ListT m) a) -> ListT m a
- Control.Monad.ListT: Nil :: ListItem l a
- Control.Monad.ListT: data ListItem l a
- Control.Monad.ListT: foldrListT :: (Monad m) => (a -> m b -> m b) -> m b -> ListT m a -> m b
- Control.Monad.ListT: headL :: ListItem l a -> a
- Control.Monad.ListT: newtype ListT m a
- Control.Monad.ListT: runListT :: ListT m a -> m (ListItem (ListT m) a)
- Control.Monad.ListT: tailL :: ListItem l a -> l a
- Data.List.Class: convList :: ((ItemM l) ~ (ItemM k), List l, List k) => l a -> k a
- Data.List.Class: fromListT :: (List l) => ListT (ItemM l) a -> l a
- Data.List.Class: instance (Monad m) => List (ListT m)
- Data.List.Class: liftListMonad :: (MonadTrans t, Monad (t (ItemM l)), List l) => l a -> ListT (t (ItemM l)) a
- Data.List.Class: toListT :: (List l) => l a -> ListT (ItemM l) a
+ Control.Monad.ListT: data ListT m a
+ Control.Monad.ListT: instance (Eq (m (ListItem (ListT m) a))) => Eq (ListT m a)
+ Control.Monad.ListT: instance (Monad m) => List (ListT m)
+ Control.Monad.ListT: instance (Ord (m (ListItem (ListT m) a))) => Ord (ListT m a)
+ Control.Monad.ListT: instance (Read (m (ListItem (ListT m) a))) => Read (ListT m a)
+ Control.Monad.ListT: instance (Show (m (ListItem (ListT m) a))) => Show (ListT m a)
+ Data.List.Class: Cons :: a -> l a -> ListItem l a
+ Data.List.Class: Nil :: ListItem l a
+ Data.List.Class: data ListItem l a
+ Data.List.Class: headL :: ListItem l a -> a
+ Data.List.Class: instance (Eq a, Eq (l a)) => Eq (ListItem l a)
+ Data.List.Class: instance (Ord a, Ord (l a)) => Ord (ListItem l a)
+ Data.List.Class: instance (Read a, Read (l a)) => Read (ListItem l a)
+ Data.List.Class: instance (Show a, Show (l a)) => Show (ListItem l a)
+ Data.List.Class: runList :: (List l) => l a -> ItemM l (ListItem l a)
+ Data.List.Class: tailL :: ListItem l a -> l a
- Data.List.Class: class (MonadPlus l, Monad (ItemM l)) => List l where { type family ItemM l :: * -> *; { fromListT = convList toListT = convList foldrL consFunc nilFunc = foldrL consFunc nilFunc . toListT } }
+ Data.List.Class: class (MonadPlus l, Monad (ItemM l)) => List l where { type family ItemM l :: * -> *; }
- Data.List.Class: joinL :: (List l) => ItemM l (l b) -> l b
+ Data.List.Class: joinL :: (List l) => ItemM l (l a) -> l a

Files

List.cabal view
@@ -1,5 +1,5 @@ Name:                List-Version:             0.1+Version:             0.2 Category:            Control Synopsis:            List monad transformer and class Description:
src/Control/Monad/ListT.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, StandaloneDeriving, TypeFamilies, UndecidableInstances #-}  -- Module is called ListT because List is taken by mtl @@ -19,10 +19,10 @@ -- >   fmap reads . -- >   joinM $ (repeat getLine :: ListT IO (IO String)) -module Control.Monad.ListT (-  ListItem(..), ListT(..), foldrListT-) where+module Control.Monad.ListT (ListT) where +import Data.List.Class (List(..), ListItem(..), foldrL)+ import Control.Applicative (Applicative(..)) import Control.Monad (MonadPlus(..), ap, liftM) -- import Control.Monad.Cont.Class (MonadCont(..))@@ -32,27 +32,20 @@ import Control.Monad.Trans (MonadTrans(..), MonadIO(..)) import Data.Monoid (Monoid(..)) -data ListItem l a =-  Nil |-  Cons { headL :: a, tailL :: l a }--newtype ListT m a = ListT { runListT :: m (ListItem (ListT m) a) }+newtype ListT m a =+  ListT { runListT :: m (ListItem (ListT m) a) } --- | foldr for ListT-foldrListT :: Monad m => (a -> m b -> m b) -> m b -> ListT m a -> m b-foldrListT consFunc nilFunc list = do-  item <- runListT list-  case item of-    Nil -> nilFunc-    Cons x xs -> consFunc x $ foldrListT consFunc nilFunc xs+deriving instance (Eq (m (ListItem (ListT m) a))) => Eq (ListT m a)+deriving instance (Ord (m (ListItem (ListT m) a))) => Ord (ListT m a)+deriving instance (Read (m (ListItem (ListT m) a))) => Read (ListT m a)+deriving instance (Show (m (ListItem (ListT m) a))) => Show (ListT m a)  -- for mappend, fmap, bind-foldrListT' :: Monad m =>-  (a -> ListT m b -> ListT m b) -> ListT m b -> ListT m a -> ListT m b-foldrListT' consFunc nilFunc =-  ListT . foldrListT step (runListT nilFunc)+foldrL' :: List l => (a -> l b -> l b) -> l b -> l a -> l b+foldrL' consFunc nilFunc =+  joinL . foldrL step (return nilFunc)   where-    step x = runListT . consFunc x . ListT+    step x = return . consFunc x . joinL  -- like generic cons except using that one -- would cause an infinite loop@@ -61,14 +54,14 @@  instance Monad m => Monoid (ListT m a) where   mempty = ListT $ return Nil-  mappend = flip (foldrListT' cons)+  mappend = flip (foldrL' cons)  instance Monad m => Functor (ListT m) where-  fmap func = foldrListT' (cons . func) mempty+  fmap func = foldrL' (cons . func) mempty  instance Monad m => Monad (ListT m) where   return = ListT . return . (`Cons` mempty)-  a >>= b = foldrListT' mappend mempty $ fmap b a+  a >>= b = foldrL' mappend mempty (fmap b a)  instance Monad m => Applicative (ListT m) where   pure = return@@ -81,6 +74,11 @@ instance MonadTrans ListT where   lift = ListT . liftM (`Cons` mempty) +instance Monad m => List (ListT m) where+  type ItemM (ListT m) = m+  runList = runListT+  joinL = ListT . (>>= runList)+ -- YUCK: -- I can't believe I'm doing this, -- for compatability with mtl's ListT.@@ -100,11 +98,11 @@  instance MonadError e m => MonadError e (ListT m) where   throwError = lift . throwError-  catchError m = ListT . catchError (runListT m) . (runListT .)+  catchError m = ListT . catchError (runList m) . (runList .)  instance MonadReader s m => MonadReader s (ListT m) where   ask = lift ask-  local f = ListT . local f . runListT+  local f = ListT . local f . runList  instance MonadState s m => MonadState s (ListT m) where   get = lift get
src/Data/List/Class.hs view
@@ -4,65 +4,58 @@  module Data.List.Class (   -- | The List typeclass-  List (..),+  List (..), ListItem (..),   -- | List operations for MonadPlus   cons, fromList, filter, repeat,   -- | Standard list operations   takeWhile, genericTake, scanl,   transpose, zip, zipWith,   -- | Non standard List operations-  foldlL, toList, lengthL, lastL,+  foldrL, foldlL, toList, lengthL, lastL,   merge2On, mergeOn,   -- | Operations useful for monadic lists   execute, joinM,   -- | Convert between List types-  convList, transformListMonad, liftListMonad+  transformListMonad   ) where -import Control.Monad (MonadPlus(..), ap, join, liftM)+import Control.Monad (MonadPlus(..), liftM) import Control.Monad.Identity (Identity(..))-import Control.Monad.ListT (ListT(..), ListItem(..), foldrListT)-import Control.Monad.Trans (MonadTrans(..)) import Data.Function (fix)+import Data.Maybe (fromJust) import Prelude hiding (   filter, repeat, scanl, takeWhile, zip, zipWith) +data ListItem l a =+  Nil |+  Cons { headL :: a, tailL :: l a }+  deriving (Eq, Ord, Read, Show)+ -- | A class for list types. -- Every list has an underlying monad. class (MonadPlus l, Monad (ItemM l)) => List l where   type ItemM l :: * -> *+  runList :: l a -> ItemM l (ListItem l a)   -- | Transform an action returning a list to the returned list   --   -- > > joinL $ Identity "hello"   -- > "hello"-  joinL :: ItemM l (l b) -> l b-  -- | foldr for 'List's.-  -- the result and 'right side' values are monadic actions.-  foldrL :: (a -> ItemM l b -> ItemM l b) -> ItemM l b -> l a -> ItemM l b-  foldrL consFunc nilFunc = foldrL consFunc nilFunc . toListT-  -- | Convert to a 'ListT'.-  ---  -- Can be done with a foldrL but included in type-class for efficiency.-  toListT :: l a -> ListT (ItemM l) a-  toListT = convList-  -- | Convert from a 'ListT'.-  ---  -- Can be done with a foldrL but included in type-class for efficiency.-  fromListT :: ListT (ItemM l) a -> l a-  fromListT = convList+  joinL :: ItemM l (l a) -> l a  instance List [] where   type ItemM [] = Identity+  runList [] = Identity Nil+  runList (x:xs) = Identity $ Cons x xs   joinL = runIdentity-  foldrL = foldr-  toListT = fromList -instance Monad m => List (ListT m) where-  type ItemM (ListT m) = m-  joinL = ListT . (>>= runListT)-  foldrL = foldrListT-  toListT = id-  fromListT = id+-- | foldr for 'List's.+-- the result and 'right side' values are monadic actions.+foldrL :: List l => (a -> ItemM l b -> ItemM l b) -> ItemM l b -> l a -> ItemM l b+foldrL consFunc nilFunc list = do+  item <- runList list+  case item of+    Nil -> nilFunc+    Cons x xs -> consFunc x (foldrL consFunc nilFunc xs)  -- | Prepend an item to a 'MonadPlus' cons :: MonadPlus m => a -> m a -> m a@@ -77,13 +70,6 @@ fromList :: MonadPlus m => [a] -> m a fromList = foldr (mplus . return) mzero --- | Convert between lists with the same underlying monad-convList :: (ItemM l ~ ItemM k, List l, List k) => l a -> k a-convList =-  joinL . foldrL step (return mzero)-  where-    step x = return . cons x . joinL- -- | filter for any MonadPlus -- -- > > filter (> 5) (Just 3)@@ -96,39 +82,33 @@       | cond x = return x       | otherwise = mzero --- for foldlL and scanl-foldlL' :: List l =>-  (a -> (ItemM l) c -> c) -> (a -> c) ->-  (a -> b -> a) -> a -> l b -> c-foldlL' joinVals atEnd step startVal =-  t startVal . foldrL astep (return atEnd)-  where-    astep x rest = return $ (`t` rest) . (`step` x)-    t cur = joinVals cur . (`ap` return cur)- -- | An action to do foldl for 'List's foldlL :: List l => (a -> b -> a) -> a -> l b -> ItemM l a-foldlL step startVal =-  foldlL' (const join) id astep (return startVal)-  where-    astep rest x = liftM (`step` x) rest+foldlL step startVal list = do+  item <- runList list+  case item of+    Nil -> return startVal+    Cons x xs ->+      let v = step startVal x+      in v `seq` foldlL step v xs  scanl :: List l => (a -> b -> a) -> a -> l b -> l a-scanl =-  foldlL' consJoin $ const mzero-  where-    consJoin cur = cons cur . joinL+scanl step startVal list =+  cons startVal . joinL $ do+    item <- runList list+    return $ case item of+      Nil -> mzero+      Cons x xs -> scanl step (step startVal x) xs  genericTake :: (Integral i, List l) => i -> l a -> l a-genericTake count-  | count <= 0 = const mzero-  | otherwise = foldlL' joinStep (const mzero) next Nothing-  where-    next Nothing x = Just (count, x)-    next (Just (i, _)) y = Just (i - 1, y)-    joinStep Nothing = joinL-    joinStep (Just (1, x)) = const $ return x-    joinStep (Just (_, x)) = cons x . joinL+genericTake count list+  | count <= 0 = mzero+  | otherwise =+    joinL $ do+      item <- runList list+      return $ case item of+        Nil -> mzero+        Cons x xs -> cons x (genericTake (count-1) xs)  -- | Execute the monadic actions in a 'List' execute :: List l => l a -> ItemM l ()@@ -142,9 +122,8 @@ joinM =   joinL . foldrL consFunc (return mzero)   where-    consFunc action rest = do-      x <- action-      return . cons x . joinL $ rest+    consFunc action rest =+      liftM (`cons` joinL rest) action  takeWhile :: List l => (a -> Bool) -> l a -> l a takeWhile cond =@@ -152,7 +131,7 @@   where     step x       | cond x = return . cons x . joinL-      | otherwise = const $ return mzero+      | otherwise = const (return mzero)  -- | An action to transform a 'List' to a list --@@ -160,7 +139,7 @@ -- > "hello!" toList :: List l => l a -> ItemM l [a] toList =-  foldrL step $ return []+  foldrL step (return [])   where     step = liftM . (:) @@ -184,32 +163,17 @@     t = joinL . trans     step x = return . cons x . t --- | Lift the underlying monad of a list and transform it to a ListT.------ Doing plain 'transformListMonad lift' instead doesn't give the compiler--- the same knowledge about the types.-liftListMonad ::-  (MonadTrans t, Monad (t (ItemM l)), List l) =>-  l a -> ListT (t (ItemM l)) a-liftListMonad = transformListMonad lift- zip :: List l => l a -> l b -> l (a, b)-zip as bs =-  r0 (toListT as) (toListT bs)-  where-    r0 xx yy =-      joinL $ do-        xi <- runListT xx-        case xi of-          Nil -> return mzero-          Cons x xs -> r1 x xs yy-    r1 :: List l => a -> ListT (ItemM l) a -> ListT (ItemM l) b -> ItemM l (l (a, b))-    r1 x xs yy = do-      yi <- runListT yy-      return $ case yi of-        Nil -> mzero-        Cons y ys ->-          cons (x, y) $ r0 xs ys+zip xx yy =+  joinL $ do+    xi <- runList xx+    case xi of+      Nil -> return mzero+      Cons x xs -> do+        yi <- runList yy+        return $ case yi of+          Nil -> mzero+          Cons y ys -> cons (x, y) (zip xs ys)  -- zipWith based on zip and not vice versa, -- because the other way around hlint compains "use zip".@@ -221,17 +185,17 @@ -- > > runIdentity $ lastL "hello" -- > 'o' lastL :: List l => l a -> ItemM l a-lastL = foldlL (const id) undefined+lastL = liftM fromJust . foldlL (const Just) Nothing  repeat :: MonadPlus m => a -> m a repeat = fix . cons  transpose :: List l => l (l a) -> l (l a) transpose matrix =-  joinL $ toList matrix >>= r . map toListT+  joinL $ toList matrix >>= r   where     r xs = do-      items <- mapM runListT xs+      items <- mapM runList xs       return $ case filter isCons items of         [] -> mzero         citems ->@@ -253,9 +217,9 @@ -- > "01235689" merge2On :: (Ord b, List l) => (a -> b) -> l a -> l a -> l a merge2On f xx yy =-  fromListT . joinL $ do-    xi <- runListT (toListT xx)-    yi <- runListT (toListT yy)+  joinL $ do+    xi <- runList xx+    yi <- runList yy     return $ case (xi, yi) of       (Cons x xs, Cons y ys)         | f y > f x -> cons x . merge2On f xs $ cons y ys