packages feed

constrained-monads 0.1.0.0 → 0.2.0.0

raw patch · 2 files changed

+91/−147 lines, 2 filesdep +constraintsPVP ok

version bump matches the API change (PVP)

Dependencies added: constraints

API changes (from Hackage documentation)

- Control.Monad.Constrained: [:*] :: f x -> AppVect f xs -> AppVect f (x : xs)
- Control.Monad.Constrained: [:-] :: x -> Vect xs -> Vect (x : xs)
- Control.Monad.Constrained: [NilA] :: AppVect f '[]
- Control.Monad.Constrained: data Vect xs
- Control.Monad.Constrained: liftA4 :: (Applicative f, Suitable f e) => (a -> b -> c -> d -> e) -> f a -> f b -> f c -> f d -> f e
- Control.Monad.Constrained: liftA5 :: (Applicative f, Suitable f g) => (a -> b -> c -> d -> e -> g) -> f a -> f b -> f c -> f d -> f e -> f g
- Control.Monad.Constrained: liftA6 :: (Applicative f, Suitable f h) => (a -> b -> c -> d -> e -> g -> h) -> f a -> f b -> f c -> f d -> f e -> f g -> f h
- Control.Monad.Constrained: liftA7 :: (Applicative f, Suitable f i) => (a -> b -> c -> d -> e -> g -> h -> i) -> f a -> f b -> f c -> f d -> f e -> f g -> f h -> f i
- Control.Monad.Constrained: liftA8 :: (Applicative f, Suitable f j) => (a -> b -> c -> d -> e -> g -> h -> i -> j) -> f a -> f b -> f c -> f d -> f e -> f g -> f h -> f i -> f j
- Control.Monad.Constrained: liftA9 :: (Applicative f, Suitable f k) => (a -> b -> c -> d -> e -> g -> h -> i -> j -> k) -> f a -> f b -> f c -> f d -> f e -> f g -> f h -> f i -> f j -> f k
+ Control.Monad.Constrained: [:>] :: AppVect f xs -> f x -> AppVect f (x : xs)
- Control.Monad.Constrained: [Nil] :: Vect '[]
+ Control.Monad.Constrained: [Nil] :: AppVect f '[]
- Control.Monad.Constrained: class Functor f => Applicative f where pure x = liftA (\ Nil -> x) NilA fs <*> xs = liftA (\ (f :- x :- Nil) -> f x) (fs :* xs :* NilA) (*>) = liftA2 (const id) (<*) = liftA2 const liftA2 f xs ys = liftA (\ (x :- y :- Nil) -> f x y) (xs :* ys :* NilA) liftA3 f xs ys zs = liftA (\ (x :- y :- z :- Nil) -> f x y z) (xs :* ys :* zs :* NilA) liftA4 f ws xs ys zs = liftA (\ (w :- x :- y :- z :- Nil) -> f w x y z) (ws :* xs :* ys :* zs :* NilA) liftA5 f vs ws xs ys zs = liftA (\ (v :- w :- x :- y :- z :- Nil) -> f v w x y z) (vs :* ws :* xs :* ys :* zs :* NilA) liftA6 f us vs ws xs ys zs = liftA (\ (u :- v :- w :- x :- y :- z :- Nil) -> f u v w x y z) (us :* vs :* ws :* xs :* ys :* zs :* NilA) liftA7 f ts us vs ws xs ys zs = liftA (\ (t :- u :- v :- w :- x :- y :- z :- Nil) -> f t u v w x y z) (ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA) liftA8 f ss ts us vs ws xs ys zs = liftA (\ (s :- t :- u :- v :- w :- x :- y :- z :- Nil) -> f s t u v w x y z) (ss :* ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA) liftA9 f rs ss ts us vs ws xs ys zs = liftA (\ (r :- s :- t :- u :- v :- w :- x :- y :- z :- Nil) -> f r s t u v w x y z) (rs :* ss :* ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA)
+ Control.Monad.Constrained: class Functor f => Applicative f where pure x = liftA x Nil fs <*> xs = liftA ($) (Nil :> fs :> xs) (*>) = liftA2 (const id) (<*) = liftA2 const liftA2 f xs ys = liftA f (Nil :> xs :> ys) liftA3 f xs ys zs = liftA f (Nil :> xs :> ys :> zs)
- Control.Monad.Constrained: liftA :: (Applicative f, Suitable f b) => (Vect xs -> b) -> AppVect f xs -> f b
+ Control.Monad.Constrained: liftA :: (Applicative f, Suitable f a) => FunType xs a -> AppVect f xs -> f a
- Control.Monad.Constrained: liftAM :: (Monad f, Suitable f b) => (Vect xs -> b) -> (AppVect f xs -> f b)
+ Control.Monad.Constrained: liftAM :: (Monad f, Suitable f a) => FunType xs a -> AppVect f xs -> f a
- Control.Monad.Constrained: liftAP :: (Applicative f) => (Vect xs -> b) -> (AppVect f xs -> f b)
+ Control.Monad.Constrained: liftAP :: Applicative f => FunType xs a -> AppVect f xs -> f a

Files

constrained-monads.cabal view
@@ -1,5 +1,5 @@ name:                constrained-monads-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Typeclasses and instances for monads with constraints.  description:         A library for monads with constraints over the types they contain. This allows set, etc to conform to the monad class. It is structured as a prelude replacement: everything that doesn't conflict with the new definitions of 'Functor', 'Monad', etc is reexported.                      @@ -27,6 +27,7 @@   build-depends:       base >= 4.9 && < 5                      , containers >= 0.5                      , transformers >= 0.5+                     , constraints >= 0.8   default-language:    Haskell2010   ghc-options:         -Wall 
src/Control/Monad/Constrained.hs view
@@ -1,12 +1,14 @@ {-# LANGUAGE ConstraintKinds      #-}-{-# LANGUAGE DataKinds            #-} {-# LANGUAGE BangPatterns         #-}+{-# LANGUAGE DataKinds            #-} {-# LANGUAGE GADTs                #-} {-# LANGUAGE LambdaCase           #-} {-# LANGUAGE RebindableSyntax     #-} {-# LANGUAGE TypeFamilies         #-} {-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE RankNTypes           #-}  -- | A module for constrained monads. This module is intended to be imported -- with the @-XRebindableSyntax@ extension turned on: everything from the@@ -23,8 +25,8 @@   ,Traversable(..)   ,    -- * Horrible type-level stuff-   Vect(..)-  ,AppVect(..)+  AppVect(..)+  ,FunType   ,liftAP   ,liftAM   ,@@ -81,29 +83,27 @@ import           Control.Monad.Trans.Reader       (ReaderT (..), mapReaderT) import           Control.Monad.Trans.State        (StateT (..)) import qualified Control.Monad.Trans.State.Strict as Strict (StateT (..))-import           Control.Monad.Trans.State.Strict (state, runState)  import           Control.Arrow (first)-import           Data.Tuple (swap)+import           Data.Tuple+import           Control.Monad.Trans.State.Strict (state, runState)  -------------------------------------------------------------------------------- -- Type-level shenanigans -------------------------------------------------------------------------------- --- | A heterogeneous list, for storing the arguments to 'liftA'. (There /has/ to--- be a better way to do this).-infixr 5 :--data Vect xs where-  Nil  :: Vect '[]-  (:-) :: x -> Vect xs -> Vect (x ': xs)---- | Another heterogeneous list, for storing the arguments to 'liftA', wrapped--- in their applicatives.-infixr 5 :*+-- | A heterogeneous snoc list, for storing the arguments to 'liftA',+-- wrapped in their applicatives.+infixl 5 :> data AppVect f xs where-  NilA :: AppVect f '[]-  (:*) :: f x -> AppVect f xs -> AppVect f (x ': xs)+  Nil :: AppVect f '[]+  (:>) :: AppVect f xs -> f x -> AppVect f (x ': xs) +-- | The type of a function for 'liftA'.+type family FunType (xs :: [*]) (y :: *) :: * where+  FunType '[] y = y+  FunType (x ': xs) y = FunType xs (x -> y)+ -------------------------------------------------------------------------------- -- Standard classes --------------------------------------------------------------------------------@@ -214,7 +214,7 @@     pure         :: Suitable f a         => a -> f a-    pure x = liftA (\Nil -> x) NilA+    pure x = liftA x Nil     {-# INLINE pure #-}      infixl 4 <*>@@ -223,7 +223,7 @@     (<*>)         :: Suitable f b         => f (a -> b) -> f a -> f b-    fs <*> xs = liftA (\(f :- x :- Nil) -> f x) (fs :* xs :* NilA)+    fs <*> xs = liftA ($) (Nil :> fs :> xs)     {-# INLINE (<*>) #-}      infixl 4 *>@@ -276,9 +276,8 @@     -- to get do-notation to desugar to using the 'liftA' functions, rather     -- than @('<*>')@.     ---    -- It would also be preferable to avoid the two intermediate structures-    -- ('Vect', 'AppVect', etc). Ideally GHC would optimize them away, but-    -- it seems unlikely.+    -- From some preliminary performance testing, it seems that this approach+    -- has /no/ performance overhead.     --     -- Utility definitions of this function are provided: if your 'Applicative'     -- is a @Prelude.'Prelude.Applicative'@, 'liftA' can be defined in terms of@@ -287,133 +286,55 @@     -- Alternatively, if your applicative is a 'Monad', 'liftA' can be defined     -- in terms of @('>>=')@, which is what 'liftAM' does.     liftA-        :: Suitable f b-        => (Vect xs -> b) -> AppVect f xs -> f b+        :: Suitable f a+        => FunType xs a -> AppVect f xs -> f a      liftA2         :: Suitable f c         => (a -> b -> c) -> f a -> f b -> f c     liftA2 f xs ys =-        liftA-            (\(x :- y :- Nil) ->-                  f x y)-            (xs :* ys :* NilA)+        liftA f (Nil :> xs :> ys)+     liftA3         :: Suitable f d         => (a -> b -> c -> d) -> f a -> f b -> f c -> f d     liftA3 f xs ys zs =-        liftA-            (\(x :- y :- z :- Nil) ->-                  f x y z)-            (xs :* ys :* zs :* NilA)-    liftA4-        :: Suitable f e-        => (a -> b -> c -> d -> e) -> f a -> f b -> f c -> f d -> f e-    liftA4 f ws xs ys zs =-        liftA-            (\(w :- x :- y :- z :- Nil) ->-                  f w x y z)-            (ws :* xs :* ys :* zs :* NilA)-    liftA5-        :: Suitable f g-        => (a -> b -> c -> d -> e -> g)-        -> f a-        -> f b-        -> f c-        -> f d-        -> f e-        -> f g-    liftA5 f vs ws xs ys zs =-        liftA-            (\(v :- w :- x :- y :- z :- Nil) ->-                  f v w x y z)-            (vs :* ws :* xs :* ys :* zs :* NilA)--    liftA6-        :: Suitable f h-        => (a -> b -> c -> d -> e -> g -> h)-        -> f a-        -> f b-        -> f c-        -> f d-        -> f e-        -> f g-        -> f h-    liftA6 f us vs ws xs ys zs =-        liftA-            (\(u :- v :- w :- x :- y :- z :- Nil) ->-                  f u v w x y z)-            (us :* vs :* ws :* xs :* ys :* zs :* NilA)--    liftA7-        :: Suitable f i-        => (a -> b -> c -> d -> e -> g -> h -> i)-        -> f a-        -> f b-        -> f c-        -> f d-        -> f e-        -> f g-        -> f h-        -> f i-    liftA7 f ts us vs ws xs ys zs =-        liftA-            (\(t :- u :- v :- w :- x :- y :- z :- Nil) ->-                  f t u v w x y z)-            (ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA)--    liftA8-        :: Suitable f j-        => (a -> b -> c -> d -> e -> g -> h -> i -> j)-        -> f a-        -> f b-        -> f c-        -> f d-        -> f e-        -> f g-        -> f h-        -> f i-        -> f j-    liftA8 f ss ts us vs ws xs ys zs =-        liftA-            (\(s :- t :- u :- v :- w :- x :- y :- z :- Nil) ->-                  f s t u v w x y z)-            (ss :* ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA)+        liftA f (Nil :> xs :> ys :> zs) -    liftA9-        :: Suitable f k-        => (a -> b -> c -> d -> e -> g -> h -> i -> j -> k)-        -> f a-        -> f b-        -> f c-        -> f d-        -> f e-        -> f g-        -> f h-        -> f i-        -> f j-        -> f k-    liftA9 f rs ss ts us vs ws xs ys zs =-        liftA-            (\(r :- s :- t :- u :- v :- w :- x :- y :- z :- Nil) ->-                  f r s t u v w x y z)-            (rs :* ss :* ts :* us :* vs :* ws :* xs :* ys :* zs :* NilA)+    {-# INLINE liftA2 #-}+    {-# INLINE liftA3 #-}  -- | A variant of '<*>' with the arguments reversed. (<**>) :: (Applicative f, Suitable f b) => f a -> f (a -> b) -> f b (<**>) = liftA2 (flip ($)) +-- | A definition of 'liftA' that uses monadic operations.+liftAM :: (Monad f, Suitable f a) => FunType xs a -> AppVect f xs -> f a+liftAM = go pure where+  go :: (Suitable f b, Monad f) => (a -> f b) -> FunType xs a -> AppVect f xs -> f b+  go f g Nil = f g+  go f g (xs :> x) = go (\c -> x >>= f . c) g xs+ -- | A definition of 'liftA' which uses the "Prelude"'s @('Prelude.<*>')@.-liftAP :: (Prelude.Applicative f) => (Vect xs -> b) -> (AppVect f xs -> f b)-liftAP f NilA = Prelude.pure (f Nil)-liftAP f (x :* NilA) = Prelude.fmap (f . (:-Nil)) x-liftAP f (x :* xs) =  ((f .) . (:-)) Prelude.<$> x Prelude.<*> liftAP id xs+liftAP :: Prelude.Applicative f => FunType xs a -> AppVect f xs -> f a+liftAP f Nil = Prelude.pure f+liftAP f (Nil :> xs) = Prelude.fmap f xs+liftAP f (ys :> xs) = liftAP f ys Prelude.<*> xs+{-# INLINABLE liftAP #-} --- | A definition of 'liftA' which uses 's @('>>=')@.-liftAM :: (Monad f, Suitable f b) => (Vect xs -> b) -> (AppVect f xs -> f b)-liftAM f NilA = pure (f Nil)-liftAM f (x :* NilA) = fmap (f . (:-Nil)) x-liftAM f (x :* xs) = x >>= \y -> liftAM (f . (y:-)) xs+{-# INLINE liftA2P #-}+{-# INLINE liftA3P #-}+-- | Definitions for the various lifts using only "Prelude" functions.+liftA2P+    :: (Prelude.Applicative f)+    => (a -> b -> c) -> f a -> f b -> f c+liftA2P f x y = f Prelude.<$> x Prelude.<*> y++liftA3P+    :: Prelude.Applicative f+    => (a -> b -> c -> d) -> f a -> f b -> f c -> f d+liftA3P f xs ys zs = f Prelude.<$> xs Prelude.<*> ys Prelude.<*> zs+ {- | The 'Monad' class defines the basic operations over a /monad/, a concept from a branch of mathematics known as /category theory/. From the perspective of a Haskell programmer, however, it is best to@@ -795,11 +716,13 @@     (<$) = (Prelude.<$)  instance Applicative [] where-  liftA = liftAP-  (<*>) = (Prelude.<*>)-  (*>) = (Prelude.*>)-  (<*) = (Prelude.<*)-  pure = Prelude.pure+    liftA = liftAP+    (<*>) = (Prelude.<*>)+    (*>) = (Prelude.*>)+    (<*) = (Prelude.<*)+    pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Alternative [] where   empty = []@@ -822,6 +745,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Alternative Maybe where     empty = Control.Applicative.empty@@ -845,6 +770,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Alternative IO where     empty = Control.Applicative.empty@@ -864,12 +791,14 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monad Identity where     (>>=) = (Prelude.>>=)  instance Traversable Identity where-  traverse f (Identity x) = fmap Identity (f x)+    traverse f (Identity x) = fmap Identity (f x)  instance Functor (Either e) where     type Suitable (Either e) a = ()@@ -882,6 +811,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monad (Either a) where     (>>=) = (Prelude.>>=)@@ -905,8 +836,8 @@     (>>=) = flip foldMap  instance Alternative Set where-  empty = Set.empty-  (<|>) = Set.union+    empty = Set.empty+    (<|>) = Set.union  instance Functor (Map a) where     type Suitable (Map a) b = ()@@ -924,6 +855,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monoid a => Monad ((,) a) where     (>>=) = (Prelude.>>=)@@ -947,6 +880,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Alternative Seq where     empty = Control.Applicative.empty@@ -966,6 +901,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monad Tree where     (>>=) = (Prelude.>>=)@@ -981,6 +918,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monad ((->) a) where   (>>=) = (Prelude.>>=)@@ -996,6 +935,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Monad (ContT r m) where     (>>=) = (Prelude.>>=)@@ -1011,6 +952,8 @@     (*>) = (Prelude.*>)     (<*) = (Prelude.<*)     pure = Prelude.pure+    liftA2 = liftA2P+    liftA3 = liftA3P  instance Functor m => Functor (Strict.StateT s m) where     type Suitable (Strict.StateT s m) a = Suitable m (a, s)@@ -1114,10 +1057,10 @@     f <*> v = ReaderT $ \ r -> runReaderT f r <*> runReaderT v r     {-# INLINE (<*>) #-}     liftA f ys = ReaderT $ \r -> liftA f (tr r ys) where-      tr :: Functor m => r -> AppVect (ReaderT r m) xs -> AppVect m xs-      tr _ NilA = NilA-      tr r (xs :* NilA) = runReaderT xs r :* NilA-      tr r (x :* xs) = runReaderT x r :* tr r xs+      tr :: r -> AppVect (ReaderT r m) xs -> AppVect m xs+      tr _ Nil = Nil+      tr r (Nil :> xs) = Nil :> runReaderT xs r+      tr r (xs :> x) = tr r xs :> runReaderT x r     ReaderT xs *> ReaderT ys = ReaderT (\c -> xs c *> ys c)     ReaderT xs <* ReaderT ys = ReaderT (\c -> xs c <* ys c) @@ -1146,8 +1089,8 @@   pure x = MaybeT (pure (Just x))   MaybeT fs <*> MaybeT xs = MaybeT (liftA2 (<*>) fs xs)   liftA = liftAM-  MaybeT xs *> MaybeT ys = MaybeT (xs *> ys)-  MaybeT xs <* MaybeT ys = MaybeT (xs <* ys)+  MaybeT xs *> MaybeT ys = MaybeT (liftA2 (*>) xs ys)+  MaybeT xs <* MaybeT ys = MaybeT (liftA2 (<*) xs ys)  instance Monad m => Monad (MaybeT m) where   MaybeT x >>= f = MaybeT (x >>= maybe (pure Nothing) (runMaybeT . f))