packages feed

parameterized 0.2.0.0 → 0.3.0.0

raw patch · 9 files changed

+80/−13 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Parameterized.Data.Monoid: type PMonoid n id t u v = (PMEmpty n id, PSemigroup n t u v)
+ Parameterized.Control.Monad.Trans.State.Strict: changingState :: (s -> m (a, t)) -> ChangingState m (s, t) a
+ Parameterized.Data.Monoid: class (PSemigroup n t u v, PMEmpty n id) => PMonoid n id t u v
+ Parameterized.Data.Monoid: instance forall k (n :: k -> GHC.Types.Type) (t :: k) (u :: k) (v :: k) (id :: k). (Parameterized.Data.Semigroup.PSemigroup n t u v, Parameterized.Data.Monoid.PMEmpty n id) => Parameterized.Data.Monoid.PMonoid n id t u v

Files

README.md view
@@ -3,13 +3,20 @@  Parameterized/indexed monoids and monads using only a single parameter type variable. +Refer to [ReaderSpec.hs](https://github.com/louispan/parameterized/blob/master/test/Parameterized/Control/Monad/Trans/Reader/ReaderSpec.hs) and [StateSpec.hs](https://github.com/louispan/parameterized/blob/master/test/Parameterized/Control/Monad/Trans/State/Strict/StateSpec.hs) for example usages.+ # Changelog -* 0.1.0.0-  - Initial version with parameterized Semigroup, Monoid, Applicative, Alternative, Monad-  - Added instances for OverlappingWhichReader, DistinctWhichReader, ManyReader, ManyState, and ChangingState+* 0.3.0.0+  - PMonoid is now a class with a single instance (courtesy of georgew).+  - added fixities for backtick versions of pmappend, pappend, papply and pbind+  - added changingState constructor which results in better type inference.  * 0.2.0.0   - Renamed Pempty to PEmpty.-  - Added injective functional dependencies to PEmpty, and PEmpty.+  - Added injective functional dependencies to PMEmpty, and PEmpty.   - TypeLevel is not exported by default++* 0.1.0.0+  - Initial version with parameterized Semigroup, Monoid, Applicative, Alternative, Monad+  - Added instances for OverlappingWhichReader, DistinctWhichReader, ManyReader, ManyState, and ChangingState
parameterized.cabal view
@@ -1,5 +1,5 @@ name:                parameterized-version:             0.2.0.0+version:             0.3.0.0 synopsis:            Extensible records and polymorphic variants. description:         Parameterized/indexed monoids and monads using only a single parameter type variable. 
src/Parameterized/Control/Applicative.hs view
@@ -23,6 +23,10 @@ -- | Parameterized version of 'pure' in 'Applicative' -- An instance of this should create a parameterized unary type -- where the parameter is an identity in respect to 'papply'+-- NB. For 'Parameterized.Control.Monad.Trans.State.Strict.ChangingState',+-- the id @s@ "parameter" cannot be purely determined from @m@,+-- so unlike 'pappend' there is not functional dependency to help type inference.+-- Hint: use @ppure \@_ \@_ @id@ to specify the id type to avoid ambiguity. class PPointed (m :: k -> Type -> Type) (id :: k) where     -- | lift a value.     ppure :: a -> m id a@@ -39,16 +43,17 @@ (&<*>) :: (PApplicative m t u v) => m t (a -> b) -> m u a -> m v b (&<*>) = papply infixl 4 &<*>+infixl 4 `papply`  -- | Sequence actions, discarding the value of the first argument. (&*>) :: (PApplicative m t u v) => m t a -> m u b -> m v b a1 &*> a2 = (id <$ a1) &<*> a2-infixl 4 &<*+infixl 4 &*>  -- | Sequence actions, discarding the value of the second argument. (&<*) :: (PApplicative m t u v) => m t a -> m u b -> m v a (&<*) = pliftA2 const-infixl 4 &*> -- , &<**>+infixl 4 &<*  -- | Lift a function to actions. pliftA :: (Functor (m t)) => (a -> b) -> m t a -> m t b@@ -84,3 +89,4 @@ (&<|>) :: (PAlternative m t u v) => m t a -> m u a -> m v a (&<|>) = pappend infixl 3 &<|>+infixl 3 `pappend`
src/Parameterized/Control/Monad.hs view
@@ -26,6 +26,7 @@ (&>>=) :: PMonad m t u v => m t a -> (a -> m u b) -> m v b (&>>=) = pbind infixl 1 &>>=+infixl 1 `pbind`  (&>>) :: PMonad m t u v => m t a -> m u b -> m v b m &>> k = m &>>= \_ -> k
src/Parameterized/Control/Monad/Trans/State/Strict.hs view
@@ -102,9 +102,15 @@ -- and another ChangingState that changes state from @t@ to @u@ -- make a State that changes from @s@ to @u@ -- with the compile time constraint that all the types in (AppendUnique a b) are distinct.+-- NB. The state is in the snd position to be consistent with StateT. newtype ChangingState m st a = ChangingState     { runChangingState :: At0 st -> m (a, At1 st)-    } deriving ( G.Generic)+    } deriving (G.Generic)++-- | Prefer this to using ChangingState to construct as it results in better type inference+-- as it avoids ambiguous type variable @st@+changingState :: (s -> m (a, t)) -> ChangingState m (s, t) a+changingState = ChangingState  instance Functor m => Functor (ChangingState m st) where     fmap f m = ChangingState $ \s ->
src/Parameterized/Data/Monoid.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -19,4 +20,5 @@     pmempty :: n id  -- | Parameterized version of Monoid.-type PMonoid n id t u v = (PMEmpty n id, PSemigroup n t u v)+class (PSemigroup n t u v, PMEmpty n id) => PMonoid n id t u v+instance (PSemigroup n t u v, PMEmpty n id) => PMonoid n id t u v
src/Parameterized/Data/Semigroup.hs view
@@ -19,3 +19,4 @@ (&<>) :: (PSemigroup n t u v) => n t -> n u -> n v (&<>) = pmappend infixr 6 &<>+infixr 6 `pmappend`
test/Parameterized/Control/Monad/Trans/Reader/ReaderSpec.hs view
@@ -224,7 +224,7 @@                         ManyReader manyBoolMaybeReader                 -- the "parameter" is combined                 r' = runManyReader r :: ReaderT (Many '[Int, Bool]) Maybe String-            -- functionality of both readers in an Alternative fashion+            -- functionality of both readers in an Applicative fashion             runReaderT r' ( (5 :: Int) ./ True ./ nil) `shouldBe` Just "5.True"             runReaderT r' ( (5 :: Int) ./ False ./ nil) `shouldBe` Nothing             runReaderT r' ( (0 :: Int) ./ True ./ nil) `shouldBe` Nothing@@ -238,7 +238,7 @@                             _ -> empty                 -- the "parameter" is combined                 r' = runManyReader r :: ReaderT (Many '[Int, Bool]) Maybe String-            -- functionality of both readers in an Applicative fashion+            -- functionality of both readers in an Monad fashion             runReaderT r' ( (1 :: Int) ./ True ./ nil) `shouldBe` Just "True"             runReaderT r' ( (1 :: Int) ./ False ./ nil) `shouldBe` Nothing             runReaderT r' ( (5 :: Int) ./ True ./ nil) `shouldBe` Nothing
test/Parameterized/Control/Monad/Trans/State/Strict/StateSpec.hs view
@@ -8,7 +8,9 @@ import Parameterized.Control.Monad.Trans.State.Strict import Parameterized.Control.Monad import Data.Diverse+import Data.Functor.Identity import Data.Semigroup+import Text.Read (readMaybe) import Test.Hspec  @@ -17,6 +19,10 @@ main :: IO () main = hspec spec +-- | NB. Normally you'd use @MaybeT (StateT s) r@ and not+-- @StateT s Maybe r@ because the state is lost on failure (Nothing),+-- but for the purposes of this test, I want test funtionality of @StateT s m@+-- where m is an Alternative. manyIntMaybeState :: StateT (Many '[Int]) Maybe String manyIntMaybeState= do     s <- get@@ -39,6 +45,16 @@  -------------------------------- +intToString :: Int -> Identity (Bool, String)+intToString i = Identity (even i, show i)++stringToBool :: String -> Identity (Int, Bool)+stringToBool s = case readMaybe s of+    Nothing -> Identity (0, False)+    Just i -> Identity (i, True)++--------------------------------+ spec :: Spec spec = do @@ -72,7 +88,7 @@                         ManyState manyBoolMaybeState                 -- the "parameter" is combined                 r' = runManyState r :: StateT (Many '[Int, Bool]) Maybe String-            -- functionality of both readers in an Applicative fashion+            -- functionality of both state functions in an Applicative fashion             runStateT r' ( (5 :: Int) ./ True ./ nil) `shouldBe` Just ("5.True", (6 :: Int) ./ False ./ nil)             runStateT r' ( (5 :: Int) ./ False ./ nil) `shouldBe` Nothing             runStateT r' ( (0 :: Int) ./ True ./ nil) `shouldBe` Nothing@@ -86,10 +102,38 @@                             _ -> empty                 -- the "parameter" is combined                 r' = runManyState r :: StateT (Many '[Int, Bool]) Maybe String-            -- functionality of both readers in an Monad fashion+            -- functionality of both state functions in an Monad fashion             runStateT r' ( (1 :: Int) ./ True ./ nil) `shouldBe` Just ("True", (2 :: Int) ./ False ./ nil)             runStateT r' ( (1 :: Int) ./ False ./ nil) `shouldBe` Nothing             runStateT r' ( (5 :: Int) ./ True ./ nil) `shouldBe` Nothing             runStateT r' ( (5 :: Int) ./ False ./ nil) `shouldBe` Nothing             runStateT r' ( (0 :: Int) ./ True ./ nil) `shouldBe` Nothing             runStateT r' ( (0 :: Int) ./ False ./ nil) `shouldBe` Nothing++    describe "ChangingState" $ do+        it "ppure id doesn't change the type of the parameter" $ do+            let r1 = (ppure @_ @_ @(Int, Int) id) &<*> changingState intToString+                -- the "parameter" doesn't change+                r1' = r1 :: ChangingState Identity (Int, String) Bool+            -- functionality unchanged+            runChangingState r1' (5 :: Int) `shouldBe` Identity (False, "5")+            runChangingState r1' (10 :: Int) `shouldBe` Identity (True, "10")++        it "it can 'papply' to combine state runners 'Applicative'ly" $ do+            let r = (\b i -> show b <> "." <> show i) <$> changingState intToString &<*>+                        changingState stringToBool+                -- the "parameter" is combined+                r' = r :: ChangingState Identity (Int, Bool) String+            -- functionality of both state functions in an Applicative fashion+            runChangingState r' (5 :: Int) `shouldBe` Identity ("False.5", True)+            runChangingState r' (10 :: Int) `shouldBe` Identity ("True.10", True)++        it "it can 'pbind' to combine state runners 'Monad'ically" $ do+            let r = changingState intToString &>>= \b ->+                    changingState stringToBool &>>= \i ->+                    ppure @_ @_ @(Bool, Bool) (show b <> "." <> show i)+                -- the "parameter" is combined+                r' = r :: ChangingState Identity (Int, Bool) String+            -- functionality of both state functions in an Applicative fashion+            runChangingState r' (5 :: Int) `shouldBe` Identity ("False.5", True)+            runChangingState r' (10 :: Int) `shouldBe` Identity ("True.10", True)