From 4433916be13eda878784da0ad84bd247923e25e3 Mon Sep 17 00:00:00 2001 From: Phil Freeman Date: Sat, 1 Oct 2016 12:53:01 -0700 Subject: [PATCH 01/30] first commit --- src/Data/Generic/Rep.purs | 185 ++++++++++++++++++++++++++++++++++++++ test/Main.purs | 31 +++++++ 2 files changed, 216 insertions(+) create mode 100644 src/Data/Generic/Rep.purs create mode 100644 test/Main.purs diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs new file mode 100644 index 0000000..e695bbd --- /dev/null +++ b/src/Data/Generic/Rep.purs @@ -0,0 +1,185 @@ +module Data.Generic.Rep + ( class Generic + , to + , from + , NoConstructors + , NoArguments(..) + , Sum(..) + , Product(..) + , Constructor(..) + , Argument(..) + , Rec(..) + , Field(..) + , class GenericEq + , genericEq' + , genericEq + , class GenericOrd + , genericCompare' + , genericCompare + , class GenericSemigroup + , genericAppend' + , genericAppend + , class GenericMonoid + , genericMempty' + , genericMempty + ) where + +import Prelude + +import Data.Monoid (class Monoid, mempty) + +-- | A representation for types with no constructors. +data NoConstructors + +-- | A representation for constructors with no arguments. +data NoArguments = NoArguments + +-- | A representation for types with multiple constructors. +data Sum a b = Inl a | Inr b + +-- | A representation for constructors with multiple fields. +data Product a b = Product a b + +-- | A representation for constructors which includes the data constructor name +-- | as a type-level string. +newtype Constructor (name :: Symbol) a = Constructor a + +-- | A representation for an argument in a data constructor. +newtype Argument a = Argument a + +-- | A representation for records. +newtype Rec fields = Rec fields + +-- | A representation for a record field which includes the field name +-- | as a type-level string. +newtype Field (field :: Symbol) a = Field a + +-- | The `Generic` class asserts the existence of a type function from types +-- | to their representations using the type constructors defined in this module. +class Generic a rep | a -> rep where + to :: rep -> a + from :: a -> rep + +class GenericEq a where + genericEq' :: a -> a -> Boolean + +instance genericEqNoConstructors :: GenericEq NoConstructors where + genericEq' _ _ = true + +instance genericEqNoArguments :: GenericEq NoArguments where + genericEq' _ _ = true + +instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where + genericEq' (Inl a1) (Inl a2) = genericEq' a1 a2 + genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2 + genericEq' _ _ = false + +instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where + genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2 + +instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where + genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2 + +instance genericEqArgument :: Eq a => GenericEq (Argument a) where + genericEq' (Argument a1) (Argument a2) = a1 == a2 + +instance genericEqRec :: GenericEq a => GenericEq (Rec a) where + genericEq' (Rec a1) (Rec a2) = genericEq' a1 a2 + +instance genericEqField :: GenericEq a => GenericEq (Field name a) where + genericEq' (Field a1) (Field a2) = genericEq' a1 a2 + +-- | A `Generic` implementation of the `eq` member from the `Eq` type class. +genericEq :: forall a rep. (Generic a rep, GenericEq rep) => a -> a -> Boolean +genericEq x y = genericEq' (from x) (from y) + +class GenericOrd a where + genericCompare' :: a -> a -> Ordering + +instance genericOrdNoConstructors :: GenericOrd NoConstructors where + genericCompare' _ _ = EQ + +instance genericOrdNoArguments :: GenericOrd NoArguments where + genericCompare' _ _ = EQ + +instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) where + genericCompare' (Inl a1) (Inl a2) = genericCompare' a1 a2 + genericCompare' (Inr b1) (Inr b2) = genericCompare' b1 b2 + genericCompare' (Inl b1) (Inr b2) = LT + genericCompare' (Inr b1) (Inl b2) = GT + +instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where + genericCompare' (Product a1 b1) (Product a2 b2) = + case genericCompare' a1 a2 of + EQ -> genericCompare' b1 b2 + other -> other + +instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where + genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2 + +instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where + genericCompare' (Argument a1) (Argument a2) = compare a1 a2 + +instance genericOrdRec :: GenericOrd a => GenericOrd (Rec a) where + genericCompare' (Rec a1) (Rec a2) = genericCompare' a1 a2 + +instance genericOrdField :: GenericOrd a => GenericOrd (Field name a) where + genericCompare' (Field a1) (Field a2) = genericCompare' a1 a2 + +-- | A `Generic` implementation of the `compare` member from the `Ord` type class. +genericCompare :: forall a rep. (Generic a rep, GenericOrd rep) => a -> a -> Ordering +genericCompare x y = genericCompare' (from x) (from y) + +class GenericSemigroup a where + genericAppend' :: a -> a -> a + +instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where + genericAppend' a _ = a + +instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where + genericAppend' a _ = a + +instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where + genericAppend' (Product a1 b1) (Product a2 b2) = + Product (genericAppend' a1 a2) (genericAppend' b1 b2) + +instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where + genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2) + +instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where + genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) + +instance genericSemigroupRec :: GenericSemigroup a => GenericSemigroup (Rec a) where + genericAppend' (Rec a1) (Rec a2) = Rec (genericAppend' a1 a2) + +instance genericSemigroupField :: GenericSemigroup a => GenericSemigroup (Field name a) where + genericAppend' (Field a1) (Field a2) = Field (genericAppend' a1 a2) + +-- | A `Generic` implementation of the `append` member from the `Semigroup` type class. +genericAppend :: forall a rep. (Generic a rep, GenericSemigroup rep) => a -> a -> a +genericAppend x y = to (genericAppend' (from x) (from y)) + +class GenericMonoid a where + genericMempty' :: a + +instance genericMonoidNoArguments :: GenericMonoid NoArguments where + genericMempty' = NoArguments + +instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where + genericMempty' = Product genericMempty' genericMempty' + +instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where + genericMempty' = Constructor genericMempty' + +instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where + genericMempty' = Argument mempty + +instance genericMonoidRec :: GenericMonoid a => GenericMonoid (Rec a) where + genericMempty' = Rec genericMempty' + +instance genericMonoidField :: GenericMonoid a => GenericMonoid (Field name a) where + genericMempty' = Field genericMempty' + +-- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. +genericMempty :: forall a rep. (Generic a rep, GenericMonoid rep) => a +genericMempty = to genericMempty' diff --git a/test/Main.purs b/test/Main.purs new file mode 100644 index 0000000..cccaf5f --- /dev/null +++ b/test/Main.purs @@ -0,0 +1,31 @@ +module Test.Main where + +import Prelude +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.Console (CONSOLE, logShow) +import Data.Generic.Rep as G + +data List a = Nil | Cons a (List a) + +instance genericList :: G.Generic (List a) + (G.Sum (G.Constructor "Nil" G.NoArguments) + (G.Constructor "Cons" (G.Product (G.Argument a) + (G.Argument (List a))))) where + to (G.Inl (G.Constructor G.NoArguments)) = Nil + to (G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs)))) = Cons x xs + from Nil = G.Inl (G.Constructor G.NoArguments) + from (Cons x xs) = G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs))) + +instance eqList :: Eq a => Eq (List a) where + eq x y = G.genericEq x y + +instance ordList :: Ord a => Ord (List a) where + compare x y = G.genericCompare x y + +main :: Eff (console :: CONSOLE) Unit +main = do + logShow (Cons 1 (Cons 2 Nil) == Cons 1 (Cons 2 Nil)) + logShow (Cons 1 (Cons 2 Nil) == Cons 1 Nil) + + logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 (Cons 2 Nil)) + logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 Nil) From 98f28b47ea927656a150559bb9e84c5bfd231e9d Mon Sep 17 00:00:00 2001 From: Phil Freeman Date: Mon, 3 Oct 2016 21:07:55 -0700 Subject: [PATCH 02/30] Fix instances for record fields --- src/Data/Generic/Rep.purs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs index e695bbd..a1acc5b 100644 --- a/src/Data/Generic/Rep.purs +++ b/src/Data/Generic/Rep.purs @@ -86,8 +86,8 @@ instance genericEqArgument :: Eq a => GenericEq (Argument a) where instance genericEqRec :: GenericEq a => GenericEq (Rec a) where genericEq' (Rec a1) (Rec a2) = genericEq' a1 a2 -instance genericEqField :: GenericEq a => GenericEq (Field name a) where - genericEq' (Field a1) (Field a2) = genericEq' a1 a2 +instance genericEqField :: Eq a => GenericEq (Field name a) where + genericEq' (Field a1) (Field a2) = a1 == a2 -- | A `Generic` implementation of the `eq` member from the `Eq` type class. genericEq :: forall a rep. (Generic a rep, GenericEq rep) => a -> a -> Boolean @@ -123,8 +123,8 @@ instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where instance genericOrdRec :: GenericOrd a => GenericOrd (Rec a) where genericCompare' (Rec a1) (Rec a2) = genericCompare' a1 a2 -instance genericOrdField :: GenericOrd a => GenericOrd (Field name a) where - genericCompare' (Field a1) (Field a2) = genericCompare' a1 a2 +instance genericOrdField :: Ord a => GenericOrd (Field name a) where + genericCompare' (Field a1) (Field a2) = compare a1 a2 -- | A `Generic` implementation of the `compare` member from the `Ord` type class. genericCompare :: forall a rep. (Generic a rep, GenericOrd rep) => a -> a -> Ordering @@ -152,8 +152,8 @@ instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a instance genericSemigroupRec :: GenericSemigroup a => GenericSemigroup (Rec a) where genericAppend' (Rec a1) (Rec a2) = Rec (genericAppend' a1 a2) -instance genericSemigroupField :: GenericSemigroup a => GenericSemigroup (Field name a) where - genericAppend' (Field a1) (Field a2) = Field (genericAppend' a1 a2) +instance genericSemigroupField :: Semigroup a => GenericSemigroup (Field name a) where + genericAppend' (Field a1) (Field a2) = Field (append a1 a2) -- | A `Generic` implementation of the `append` member from the `Semigroup` type class. genericAppend :: forall a rep. (Generic a rep, GenericSemigroup rep) => a -> a -> a @@ -177,8 +177,8 @@ instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where instance genericMonoidRec :: GenericMonoid a => GenericMonoid (Rec a) where genericMempty' = Rec genericMempty' -instance genericMonoidField :: GenericMonoid a => GenericMonoid (Field name a) where - genericMempty' = Field genericMempty' +instance genericMonoidField :: Monoid a => GenericMonoid (Field name a) where + genericMempty' = Field mempty -- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. genericMempty :: forall a rep. (Generic a rep, GenericMonoid rep) => a From 4ef9d055f6f58dfffc5020561137b59f66f4f1bb Mon Sep 17 00:00:00 2001 From: Phil Freeman Date: Tue, 4 Oct 2016 19:32:10 -0700 Subject: [PATCH 03/30] Break modules up --- src/Data/Generic/Rep.purs | 140 ---------------------------- src/Data/Generic/Rep/Eq.purs | 41 ++++++++ src/Data/Generic/Rep/Monoid.purs | 33 +++++++ src/Data/Generic/Rep/Ord.purs | 45 +++++++++ src/Data/Generic/Rep/Semigroup.purs | 37 ++++++++ test/Main.purs | 6 +- 6 files changed, 160 insertions(+), 142 deletions(-) create mode 100644 src/Data/Generic/Rep/Eq.purs create mode 100644 src/Data/Generic/Rep/Monoid.purs create mode 100644 src/Data/Generic/Rep/Ord.purs create mode 100644 src/Data/Generic/Rep/Semigroup.purs diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs index a1acc5b..e88b966 100644 --- a/src/Data/Generic/Rep.purs +++ b/src/Data/Generic/Rep.purs @@ -10,24 +10,8 @@ module Data.Generic.Rep , Argument(..) , Rec(..) , Field(..) - , class GenericEq - , genericEq' - , genericEq - , class GenericOrd - , genericCompare' - , genericCompare - , class GenericSemigroup - , genericAppend' - , genericAppend - , class GenericMonoid - , genericMempty' - , genericMempty ) where -import Prelude - -import Data.Monoid (class Monoid, mempty) - -- | A representation for types with no constructors. data NoConstructors @@ -59,127 +43,3 @@ newtype Field (field :: Symbol) a = Field a class Generic a rep | a -> rep where to :: rep -> a from :: a -> rep - -class GenericEq a where - genericEq' :: a -> a -> Boolean - -instance genericEqNoConstructors :: GenericEq NoConstructors where - genericEq' _ _ = true - -instance genericEqNoArguments :: GenericEq NoArguments where - genericEq' _ _ = true - -instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where - genericEq' (Inl a1) (Inl a2) = genericEq' a1 a2 - genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2 - genericEq' _ _ = false - -instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where - genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2 - -instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where - genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2 - -instance genericEqArgument :: Eq a => GenericEq (Argument a) where - genericEq' (Argument a1) (Argument a2) = a1 == a2 - -instance genericEqRec :: GenericEq a => GenericEq (Rec a) where - genericEq' (Rec a1) (Rec a2) = genericEq' a1 a2 - -instance genericEqField :: Eq a => GenericEq (Field name a) where - genericEq' (Field a1) (Field a2) = a1 == a2 - --- | A `Generic` implementation of the `eq` member from the `Eq` type class. -genericEq :: forall a rep. (Generic a rep, GenericEq rep) => a -> a -> Boolean -genericEq x y = genericEq' (from x) (from y) - -class GenericOrd a where - genericCompare' :: a -> a -> Ordering - -instance genericOrdNoConstructors :: GenericOrd NoConstructors where - genericCompare' _ _ = EQ - -instance genericOrdNoArguments :: GenericOrd NoArguments where - genericCompare' _ _ = EQ - -instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) where - genericCompare' (Inl a1) (Inl a2) = genericCompare' a1 a2 - genericCompare' (Inr b1) (Inr b2) = genericCompare' b1 b2 - genericCompare' (Inl b1) (Inr b2) = LT - genericCompare' (Inr b1) (Inl b2) = GT - -instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where - genericCompare' (Product a1 b1) (Product a2 b2) = - case genericCompare' a1 a2 of - EQ -> genericCompare' b1 b2 - other -> other - -instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where - genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2 - -instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where - genericCompare' (Argument a1) (Argument a2) = compare a1 a2 - -instance genericOrdRec :: GenericOrd a => GenericOrd (Rec a) where - genericCompare' (Rec a1) (Rec a2) = genericCompare' a1 a2 - -instance genericOrdField :: Ord a => GenericOrd (Field name a) where - genericCompare' (Field a1) (Field a2) = compare a1 a2 - --- | A `Generic` implementation of the `compare` member from the `Ord` type class. -genericCompare :: forall a rep. (Generic a rep, GenericOrd rep) => a -> a -> Ordering -genericCompare x y = genericCompare' (from x) (from y) - -class GenericSemigroup a where - genericAppend' :: a -> a -> a - -instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where - genericAppend' a _ = a - -instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where - genericAppend' a _ = a - -instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where - genericAppend' (Product a1 b1) (Product a2 b2) = - Product (genericAppend' a1 a2) (genericAppend' b1 b2) - -instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where - genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2) - -instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where - genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) - -instance genericSemigroupRec :: GenericSemigroup a => GenericSemigroup (Rec a) where - genericAppend' (Rec a1) (Rec a2) = Rec (genericAppend' a1 a2) - -instance genericSemigroupField :: Semigroup a => GenericSemigroup (Field name a) where - genericAppend' (Field a1) (Field a2) = Field (append a1 a2) - --- | A `Generic` implementation of the `append` member from the `Semigroup` type class. -genericAppend :: forall a rep. (Generic a rep, GenericSemigroup rep) => a -> a -> a -genericAppend x y = to (genericAppend' (from x) (from y)) - -class GenericMonoid a where - genericMempty' :: a - -instance genericMonoidNoArguments :: GenericMonoid NoArguments where - genericMempty' = NoArguments - -instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where - genericMempty' = Product genericMempty' genericMempty' - -instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where - genericMempty' = Constructor genericMempty' - -instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where - genericMempty' = Argument mempty - -instance genericMonoidRec :: GenericMonoid a => GenericMonoid (Rec a) where - genericMempty' = Rec genericMempty' - -instance genericMonoidField :: Monoid a => GenericMonoid (Field name a) where - genericMempty' = Field mempty - --- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. -genericMempty :: forall a rep. (Generic a rep, GenericMonoid rep) => a -genericMempty = to genericMempty' diff --git a/src/Data/Generic/Rep/Eq.purs b/src/Data/Generic/Rep/Eq.purs new file mode 100644 index 0000000..475646b --- /dev/null +++ b/src/Data/Generic/Rep/Eq.purs @@ -0,0 +1,41 @@ +module Data.Generic.Rep.Eq + ( class GenericEq + , genericEq' + , genericEq + ) where + +import Prelude (class Eq, (==), (&&)) +import Data.Generic.Rep + +class GenericEq a where + genericEq' :: a -> a -> Boolean + +instance genericEqNoConstructors :: GenericEq NoConstructors where + genericEq' _ _ = true + +instance genericEqNoArguments :: GenericEq NoArguments where + genericEq' _ _ = true + +instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where + genericEq' (Inl a1) (Inl a2) = genericEq' a1 a2 + genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2 + genericEq' _ _ = false + +instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where + genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2 + +instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where + genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2 + +instance genericEqArgument :: Eq a => GenericEq (Argument a) where + genericEq' (Argument a1) (Argument a2) = a1 == a2 + +instance genericEqRec :: GenericEq a => GenericEq (Rec a) where + genericEq' (Rec a1) (Rec a2) = genericEq' a1 a2 + +instance genericEqField :: Eq a => GenericEq (Field name a) where + genericEq' (Field a1) (Field a2) = a1 == a2 + +-- | A `Generic` implementation of the `eq` member from the `Eq` type class. +genericEq :: forall a rep. (Generic a rep, GenericEq rep) => a -> a -> Boolean +genericEq x y = genericEq' (from x) (from y) diff --git a/src/Data/Generic/Rep/Monoid.purs b/src/Data/Generic/Rep/Monoid.purs new file mode 100644 index 0000000..f543641 --- /dev/null +++ b/src/Data/Generic/Rep/Monoid.purs @@ -0,0 +1,33 @@ +module Data.Generic.Rep.Monoid + ( class GenericMonoid + , genericMempty' + , genericMempty + ) where + +import Data.Monoid (class Monoid, mempty) +import Data.Generic.Rep + +class GenericMonoid a where + genericMempty' :: a + +instance genericMonoidNoArguments :: GenericMonoid NoArguments where + genericMempty' = NoArguments + +instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where + genericMempty' = Product genericMempty' genericMempty' + +instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where + genericMempty' = Constructor genericMempty' + +instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where + genericMempty' = Argument mempty + +instance genericMonoidRec :: GenericMonoid a => GenericMonoid (Rec a) where + genericMempty' = Rec genericMempty' + +instance genericMonoidField :: Monoid a => GenericMonoid (Field name a) where + genericMempty' = Field mempty + +-- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. +genericMempty :: forall a rep. (Generic a rep, GenericMonoid rep) => a +genericMempty = to genericMempty' diff --git a/src/Data/Generic/Rep/Ord.purs b/src/Data/Generic/Rep/Ord.purs new file mode 100644 index 0000000..e4a9c23 --- /dev/null +++ b/src/Data/Generic/Rep/Ord.purs @@ -0,0 +1,45 @@ +module Data.Generic.Rep.Ord + ( class GenericOrd + , genericCompare' + , genericCompare + ) where + +import Prelude (class Ord, compare, Ordering(..)) +import Data.Generic.Rep + +class GenericOrd a where + genericCompare' :: a -> a -> Ordering + +instance genericOrdNoConstructors :: GenericOrd NoConstructors where + genericCompare' _ _ = EQ + +instance genericOrdNoArguments :: GenericOrd NoArguments where + genericCompare' _ _ = EQ + +instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) where + genericCompare' (Inl a1) (Inl a2) = genericCompare' a1 a2 + genericCompare' (Inr b1) (Inr b2) = genericCompare' b1 b2 + genericCompare' (Inl b1) (Inr b2) = LT + genericCompare' (Inr b1) (Inl b2) = GT + +instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where + genericCompare' (Product a1 b1) (Product a2 b2) = + case genericCompare' a1 a2 of + EQ -> genericCompare' b1 b2 + other -> other + +instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where + genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2 + +instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where + genericCompare' (Argument a1) (Argument a2) = compare a1 a2 + +instance genericOrdRec :: GenericOrd a => GenericOrd (Rec a) where + genericCompare' (Rec a1) (Rec a2) = genericCompare' a1 a2 + +instance genericOrdField :: Ord a => GenericOrd (Field name a) where + genericCompare' (Field a1) (Field a2) = compare a1 a2 + +-- | A `Generic` implementation of the `compare` member from the `Ord` type class. +genericCompare :: forall a rep. (Generic a rep, GenericOrd rep) => a -> a -> Ordering +genericCompare x y = genericCompare' (from x) (from y) diff --git a/src/Data/Generic/Rep/Semigroup.purs b/src/Data/Generic/Rep/Semigroup.purs new file mode 100644 index 0000000..a70afab --- /dev/null +++ b/src/Data/Generic/Rep/Semigroup.purs @@ -0,0 +1,37 @@ +module Data.Generic.Rep.Semigroup + ( class GenericSemigroup + , genericAppend' + , genericAppend + ) where + +import Prelude (class Semigroup, append) +import Data.Generic.Rep + +class GenericSemigroup a where + genericAppend' :: a -> a -> a + +instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where + genericAppend' a _ = a + +instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where + genericAppend' a _ = a + +instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where + genericAppend' (Product a1 b1) (Product a2 b2) = + Product (genericAppend' a1 a2) (genericAppend' b1 b2) + +instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where + genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2) + +instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where + genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) + +instance genericSemigroupRec :: GenericSemigroup a => GenericSemigroup (Rec a) where + genericAppend' (Rec a1) (Rec a2) = Rec (genericAppend' a1 a2) + +instance genericSemigroupField :: Semigroup a => GenericSemigroup (Field name a) where + genericAppend' (Field a1) (Field a2) = Field (append a1 a2) + +-- | A `Generic` implementation of the `append` member from the `Semigroup` type class. +genericAppend :: forall a rep. (Generic a rep, GenericSemigroup rep) => a -> a -> a +genericAppend x y = to (genericAppend' (from x) (from y)) diff --git a/test/Main.purs b/test/Main.purs index cccaf5f..8f64eed 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -4,6 +4,8 @@ import Prelude import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, logShow) import Data.Generic.Rep as G +import Data.Generic.Rep.Eq as GEq +import Data.Generic.Rep.Ord as GOrd data List a = Nil | Cons a (List a) @@ -17,10 +19,10 @@ instance genericList :: G.Generic (List a) from (Cons x xs) = G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs))) instance eqList :: Eq a => Eq (List a) where - eq x y = G.genericEq x y + eq x y = GEq.genericEq x y instance ordList :: Ord a => Ord (List a) where - compare x y = G.genericCompare x y + compare x y = GOrd.genericCompare x y main :: Eff (console :: CONSOLE) Unit main = do From 3535d0299582566c83d64afa9f8449f5877d6f02 Mon Sep 17 00:00:00 2001 From: Phil Freeman Date: Sat, 10 Dec 2016 19:06:31 -0800 Subject: [PATCH 04/30] Deriving Show (#5) * Initial work on deriving Show * Add test for Show * Remove import * Travis etc. --- src/Data/Generic/Rep/Show.purs | 70 ++++++++++++++++++++++++++++++++++ test/Main.purs | 28 +++++++------- 2 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 src/Data/Generic/Rep/Show.purs diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs new file mode 100644 index 0000000..cab2695 --- /dev/null +++ b/src/Data/Generic/Rep/Show.purs @@ -0,0 +1,70 @@ +module Data.Generic.Rep.Show + ( class GenericShow + , genericShow' + , genericShow + , class GenericShowArgs + , genericShowArgs + , class GenericShowFields + , genericShowFields + ) where + +import Prelude (class Show, show, (<>)) +import Data.Foldable (intercalate) +import Data.Generic.Rep +import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol) + +class GenericShow a where + genericShow' :: a -> String + +class GenericShowArgs a where + genericShowArgs :: a -> Array String + +class GenericShowFields a where + genericShowFields :: a -> Array String + +instance genericShowNoConstructors :: GenericShow NoConstructors where + genericShow' a = genericShow' a + +instance genericShowArgsNoArguments :: GenericShowArgs NoArguments where + genericShowArgs _ = [] + +instance genericShowSum :: (GenericShow a, GenericShow b) => GenericShow (Sum a b) where + genericShow' (Inl a) = genericShow' a + genericShow' (Inr b) = genericShow' b + +instance genericShowArgsProduct + :: (GenericShowArgs a, GenericShowArgs b) + => GenericShowArgs (Product a b) where + genericShowArgs (Product a b) = genericShowArgs a <> genericShowArgs b + +instance genericShowFieldsProduct + :: (GenericShowFields a, GenericShowFields b) + => GenericShowFields (Product a b) where + genericShowFields (Product a b) = genericShowFields a <> genericShowFields b + +instance genericShowConstructor + :: (GenericShowArgs a, IsSymbol name) + => GenericShow (Constructor name a) where + genericShow' (Constructor a) = + case genericShowArgs a of + [] -> ctor + args -> "(" <> intercalate " " ([ctor] <> args) <> ")" + where + ctor :: String + ctor = reflectSymbol (SProxy :: SProxy name) + +instance genericShowArgsArgument :: Show a => GenericShowArgs (Argument a) where + genericShowArgs (Argument a) = [show a] + +instance genericShowArgsRec :: GenericShowFields a => GenericShowArgs (Rec a) where + genericShowArgs (Rec a) = ["{ " <> intercalate ", " (genericShowFields a) <> " }"] + +instance genericShowFieldsField + :: (Show a, IsSymbol name) + => GenericShowFields (Field name a) where + genericShowFields (Field a) = + [reflectSymbol (SProxy :: SProxy name) <> ": " <> show a] + +-- | A `Generic` implementation of the `show` member from the `Show` type class. +genericShow :: forall a rep. (Generic a rep, GenericShow rep) => a -> String +genericShow x = genericShow' (from x) diff --git a/test/Main.purs b/test/Main.purs index 8f64eed..f8383f6 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -6,17 +6,14 @@ import Control.Monad.Eff.Console (CONSOLE, logShow) import Data.Generic.Rep as G import Data.Generic.Rep.Eq as GEq import Data.Generic.Rep.Ord as GOrd +import Data.Generic.Rep.Show as GShow -data List a = Nil | Cons a (List a) +data List a = Nil | Cons { head :: a, tail :: List a } -instance genericList :: G.Generic (List a) - (G.Sum (G.Constructor "Nil" G.NoArguments) - (G.Constructor "Cons" (G.Product (G.Argument a) - (G.Argument (List a))))) where - to (G.Inl (G.Constructor G.NoArguments)) = Nil - to (G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs)))) = Cons x xs - from Nil = G.Inl (G.Constructor G.NoArguments) - from (Cons x xs) = G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs))) +cons :: forall a. a -> List a -> List a +cons head tail = Cons { head, tail } + +derive instance genericList :: G.Generic (List a) _ instance eqList :: Eq a => Eq (List a) where eq x y = GEq.genericEq x y @@ -24,10 +21,15 @@ instance eqList :: Eq a => Eq (List a) where instance ordList :: Ord a => Ord (List a) where compare x y = GOrd.genericCompare x y +instance showList :: Show a => Show (List a) where + show x = GShow.genericShow x + main :: Eff (console :: CONSOLE) Unit main = do - logShow (Cons 1 (Cons 2 Nil) == Cons 1 (Cons 2 Nil)) - logShow (Cons 1 (Cons 2 Nil) == Cons 1 Nil) + logShow (cons 1 (cons 2 Nil)) + + logShow (cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil)) + logShow (cons 1 (cons 2 Nil) == cons 1 Nil) - logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 (Cons 2 Nil)) - logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 Nil) + logShow (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil)) + logShow (cons 1 (cons 2 Nil) `compare` cons 1 Nil) From 36804af0aa85f616d2dd7ab35cfbd5d951bb7e92 Mon Sep 17 00:00:00 2001 From: Matthew Leon Date: Wed, 11 Jan 2017 17:54:55 +0000 Subject: [PATCH 05/30] Data.Generic.Rep.Bounded (#6) * Data.Generic.Rep.Bounded Generic implementations of Prelude.Bounded class's top and bottom. * GenericBounded - don't support product types * GenericBounded - only support NoArguments --- src/Data/Generic/Rep/Bounded.purs | 42 +++++++++++++++++++++++++++++++ test/Main.purs | 16 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Data/Generic/Rep/Bounded.purs diff --git a/src/Data/Generic/Rep/Bounded.purs b/src/Data/Generic/Rep/Bounded.purs new file mode 100644 index 0000000..eedb325 --- /dev/null +++ b/src/Data/Generic/Rep/Bounded.purs @@ -0,0 +1,42 @@ +module Data.Generic.Rep.Bounded + ( class GenericBottom + , genericBottom' + , genericBottom + , class GenericTop + , genericTop' + , genericTop + ) where + +import Data.Generic.Rep + +class GenericBottom a where + genericBottom' :: a + +instance genericBottomNoArguments :: GenericBottom NoArguments where + genericBottom' = NoArguments + +instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where + genericBottom' = Inl genericBottom' + +instance genericBottomConstructor :: GenericBottom a => GenericBottom (Constructor name a) where + genericBottom' = Constructor genericBottom' + +class GenericTop a where + genericTop' :: a + +instance genericTopNoArguments :: GenericTop NoArguments where + genericTop' = NoArguments + +instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where + genericTop' = Inr genericTop' + +instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a) where + genericTop' = Constructor genericTop' + +-- | A `Generic` implementation of the `bottom` member from the `Bounded` type class. +genericBottom :: forall a rep. (Generic a rep, GenericBottom rep) => a +genericBottom = to genericBottom' + +-- | A `Generic` implementation of the `top` member from the `Bounded` type class. +genericTop :: forall a rep. (Generic a rep, GenericTop rep) => a +genericTop = to genericTop' diff --git a/test/Main.purs b/test/Main.purs index f8383f6..d661c9b 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -7,6 +7,7 @@ import Data.Generic.Rep as G import Data.Generic.Rep.Eq as GEq import Data.Generic.Rep.Ord as GOrd import Data.Generic.Rep.Show as GShow +import Data.Generic.Rep.Bounded as GBounded data List a = Nil | Cons { head :: a, tail :: List a } @@ -24,6 +25,18 @@ instance ordList :: Ord a => Ord (List a) where instance showList :: Show a => Show (List a) where show x = GShow.genericShow x +data SimpleBounded = A | B | C | D +derive instance genericSimpleBounded :: G.Generic SimpleBounded _ +instance eqSimpleBounded :: Eq SimpleBounded where + eq x y = GEq.genericEq x y +instance ordSimpleBounded :: Ord SimpleBounded where + compare x y = GOrd.genericCompare x y +instance showSimpleBounded :: Show SimpleBounded where + show x = GShow.genericShow x +instance boundedSimpleBounded :: Bounded SimpleBounded where + bottom = GBounded.genericBottom + top = GBounded.genericTop + main :: Eff (console :: CONSOLE) Unit main = do logShow (cons 1 (cons 2 Nil)) @@ -33,3 +46,6 @@ main = do logShow (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil)) logShow (cons 1 (cons 2 Nil) `compare` cons 1 Nil) + + logShow (bottom :: SimpleBounded) + logShow (top :: SimpleBounded) From 1d325b3fad4deeaa471332062dae444ef4bb290d Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Sun, 12 Mar 2017 15:02:41 +0000 Subject: [PATCH 06/30] Update for PureScript 0.11 --- src/Data/Generic/Rep/Bounded.purs | 4 ++-- src/Data/Generic/Rep/Eq.purs | 2 +- src/Data/Generic/Rep/Monoid.purs | 2 +- src/Data/Generic/Rep/Ord.purs | 2 +- src/Data/Generic/Rep/Semigroup.purs | 2 +- src/Data/Generic/Rep/Show.purs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Data/Generic/Rep/Bounded.purs b/src/Data/Generic/Rep/Bounded.purs index eedb325..b2eb789 100644 --- a/src/Data/Generic/Rep/Bounded.purs +++ b/src/Data/Generic/Rep/Bounded.purs @@ -34,9 +34,9 @@ instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a genericTop' = Constructor genericTop' -- | A `Generic` implementation of the `bottom` member from the `Bounded` type class. -genericBottom :: forall a rep. (Generic a rep, GenericBottom rep) => a +genericBottom :: forall a rep. Generic a rep => GenericBottom rep => a genericBottom = to genericBottom' -- | A `Generic` implementation of the `top` member from the `Bounded` type class. -genericTop :: forall a rep. (Generic a rep, GenericTop rep) => a +genericTop :: forall a rep. Generic a rep => GenericTop rep => a genericTop = to genericTop' diff --git a/src/Data/Generic/Rep/Eq.purs b/src/Data/Generic/Rep/Eq.purs index 475646b..09a9ff5 100644 --- a/src/Data/Generic/Rep/Eq.purs +++ b/src/Data/Generic/Rep/Eq.purs @@ -37,5 +37,5 @@ instance genericEqField :: Eq a => GenericEq (Field name a) where genericEq' (Field a1) (Field a2) = a1 == a2 -- | A `Generic` implementation of the `eq` member from the `Eq` type class. -genericEq :: forall a rep. (Generic a rep, GenericEq rep) => a -> a -> Boolean +genericEq :: forall a rep. Generic a rep => GenericEq rep => a -> a -> Boolean genericEq x y = genericEq' (from x) (from y) diff --git a/src/Data/Generic/Rep/Monoid.purs b/src/Data/Generic/Rep/Monoid.purs index f543641..d2ceddf 100644 --- a/src/Data/Generic/Rep/Monoid.purs +++ b/src/Data/Generic/Rep/Monoid.purs @@ -29,5 +29,5 @@ instance genericMonoidField :: Monoid a => GenericMonoid (Field name a) where genericMempty' = Field mempty -- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. -genericMempty :: forall a rep. (Generic a rep, GenericMonoid rep) => a +genericMempty :: forall a rep. Generic a rep => GenericMonoid rep => a genericMempty = to genericMempty' diff --git a/src/Data/Generic/Rep/Ord.purs b/src/Data/Generic/Rep/Ord.purs index e4a9c23..0136f21 100644 --- a/src/Data/Generic/Rep/Ord.purs +++ b/src/Data/Generic/Rep/Ord.purs @@ -41,5 +41,5 @@ instance genericOrdField :: Ord a => GenericOrd (Field name a) where genericCompare' (Field a1) (Field a2) = compare a1 a2 -- | A `Generic` implementation of the `compare` member from the `Ord` type class. -genericCompare :: forall a rep. (Generic a rep, GenericOrd rep) => a -> a -> Ordering +genericCompare :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering genericCompare x y = genericCompare' (from x) (from y) diff --git a/src/Data/Generic/Rep/Semigroup.purs b/src/Data/Generic/Rep/Semigroup.purs index a70afab..e36e572 100644 --- a/src/Data/Generic/Rep/Semigroup.purs +++ b/src/Data/Generic/Rep/Semigroup.purs @@ -33,5 +33,5 @@ instance genericSemigroupField :: Semigroup a => GenericSemigroup (Field name a) genericAppend' (Field a1) (Field a2) = Field (append a1 a2) -- | A `Generic` implementation of the `append` member from the `Semigroup` type class. -genericAppend :: forall a rep. (Generic a rep, GenericSemigroup rep) => a -> a -> a +genericAppend :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a genericAppend x y = to (genericAppend' (from x) (from y)) diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs index cab2695..edd233d 100644 --- a/src/Data/Generic/Rep/Show.purs +++ b/src/Data/Generic/Rep/Show.purs @@ -66,5 +66,5 @@ instance genericShowFieldsField [reflectSymbol (SProxy :: SProxy name) <> ": " <> show a] -- | A `Generic` implementation of the `show` member from the `Show` type class. -genericShow :: forall a rep. (Generic a rep, GenericShow rep) => a -> String +genericShow :: forall a rep. Generic a rep => GenericShow rep => a -> String genericShow x = genericShow' (from x) From 0cbb8dfe2946ba3f31a055842028985f9c4339ee Mon Sep 17 00:00:00 2001 From: Liam Goodacre Date: Sat, 3 Jun 2017 22:04:33 +0100 Subject: [PATCH 07/30] Add Generic instance for Maybe (#9) --- src/Data/Generic/Rep.purs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs index e88b966..9f1c47f 100644 --- a/src/Data/Generic/Rep.purs +++ b/src/Data/Generic/Rep.purs @@ -12,6 +12,8 @@ module Data.Generic.Rep , Field(..) ) where +import Data.Maybe (Maybe(..)) + -- | A representation for types with no constructors. data NoConstructors @@ -43,3 +45,13 @@ newtype Field (field :: Symbol) a = Field a class Generic a rep | a -> rep where to :: rep -> a from :: a -> rep + +instance genericMaybe + :: Generic (Maybe a) (Sum (Constructor "Nothing" NoArguments) + (Constructor "Just" (Argument a))) where + to (Inl _) = Nothing + to (Inr (Constructor (Argument a))) = Just a + + from Nothing = Inl (Constructor NoArguments) + from (Just a) = Inr (Constructor (Argument a)) + From 75f6da8b6a807b2cf77ea4b844b9b98a9e99415d Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Sat, 5 Aug 2017 15:53:52 +0100 Subject: [PATCH 08/30] Add missing Bounded instances for Argument --- src/Data/Generic/Rep/Bounded.purs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Data/Generic/Rep/Bounded.purs b/src/Data/Generic/Rep/Bounded.purs index b2eb789..9ba33e3 100644 --- a/src/Data/Generic/Rep/Bounded.purs +++ b/src/Data/Generic/Rep/Bounded.purs @@ -9,12 +9,17 @@ module Data.Generic.Rep.Bounded import Data.Generic.Rep +import Data.Bounded (class Bounded, bottom, top) + class GenericBottom a where genericBottom' :: a instance genericBottomNoArguments :: GenericBottom NoArguments where genericBottom' = NoArguments +instance genericBottomArgument :: Bounded a => GenericBottom (Argument a) where + genericBottom' = Argument bottom + instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where genericBottom' = Inl genericBottom' @@ -27,6 +32,9 @@ class GenericTop a where instance genericTopNoArguments :: GenericTop NoArguments where genericTop' = NoArguments +instance genericTopArgument :: Bounded a => GenericTop (Argument a) where + genericTop' = Argument top + instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where genericTop' = Inr genericTop' From 793d1d470ed034bf489491ae33f72a7a2b9305e7 Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Sat, 5 Aug 2017 15:54:15 +0100 Subject: [PATCH 09/30] Add GenericEnum and GenericBoundedEnum --- src/Data/Generic/Rep/Enum.purs | 95 ++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/Data/Generic/Rep/Enum.purs diff --git a/src/Data/Generic/Rep/Enum.purs b/src/Data/Generic/Rep/Enum.purs new file mode 100644 index 0000000..767cacd --- /dev/null +++ b/src/Data/Generic/Rep/Enum.purs @@ -0,0 +1,95 @@ +module Data.Generic.Rep.Enum where + +import Prelude + +import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum) +import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Sum(..), from, to) +import Data.Generic.Rep.Bounded (class GenericBottom, class GenericTop, genericBottom', genericTop') +import Data.Maybe (Maybe(..)) +import Data.Newtype (unwrap) + +class GenericEnum a where + genericPred' :: a -> Maybe a + genericSucc' :: a -> Maybe a + +instance genericEnumNoArguments :: GenericEnum NoArguments where + genericPred' _ = Nothing + genericSucc' _ = Nothing + +instance genericEnumArgument :: Enum a => GenericEnum (Argument a) where + genericPred' (Argument a) = Argument <$> pred a + genericSucc' (Argument a) = Argument <$> succ a + +instance genericEnumConstructor :: GenericEnum a => GenericEnum (Constructor name a) where + genericPred' (Constructor a) = Constructor <$> genericPred' a + genericSucc' (Constructor a) = Constructor <$> genericSucc' a + +instance genericEnumSum :: (GenericEnum a, GenericTop a, GenericEnum b, GenericBottom b) => GenericEnum (Sum a b) where + genericPred' = case _ of + Inl a -> Inl <$> genericPred' a + Inr b -> case genericPred' b of + Nothing -> Just (Inl genericTop') + Just b' -> Just (Inr b') + genericSucc' = case _ of + Inl a -> case genericSucc' a of + Nothing -> Just (Inr genericBottom') + Just a' -> Just (Inl a') + Inr b -> Inr <$> genericSucc' b + +-- | A `Generic` implementation of the `pred` member from the `Enum` type class. +genericPred :: forall a rep. Generic a rep => GenericEnum rep => a -> Maybe a +genericPred = map to <<< genericPred' <<< from + +-- | A `Generic` implementation of the `succ` member from the `Enum` type class. +genericSucc :: forall a rep. Generic a rep => GenericEnum rep => a -> Maybe a +genericSucc = map to <<< genericSucc' <<< from + +class GenericBoundedEnum a where + genericCardinality' :: Cardinality a + genericToEnum' :: Int -> Maybe a + genericFromEnum' :: a -> Int + +instance genericBoundedEnumNoArguments :: GenericBoundedEnum NoArguments where + genericCardinality' = Cardinality 1 + genericToEnum' i = if i == 0 then Just NoArguments else Nothing + genericFromEnum' _ = 0 + +instance genericBoundedEnumArgument :: BoundedEnum a => GenericBoundedEnum (Argument a) where + genericCardinality' = Cardinality (unwrap (cardinality :: Cardinality a)) + genericToEnum' i = Argument <$> toEnum i + genericFromEnum' (Argument a) = fromEnum a + +instance genericBoundedEnumConstructor :: GenericBoundedEnum a => GenericBoundedEnum (Constructor name a) where + genericCardinality' = Cardinality (unwrap (genericCardinality' :: Cardinality a)) + genericToEnum' i = Constructor <$> genericToEnum' i + genericFromEnum' (Constructor a) = genericFromEnum' a + +instance genericBoundedEnumSum :: (GenericBoundedEnum a, GenericBoundedEnum b) => GenericBoundedEnum (Sum a b) where + genericCardinality' = + Cardinality + $ unwrap (genericCardinality' :: Cardinality a) + + unwrap (genericCardinality' :: Cardinality b) + genericToEnum' n = to genericCardinality' + where + to :: Cardinality a -> Maybe (Sum a b) + to (Cardinality ca) + | n >= 0 && n < ca = Inl <$> genericToEnum' n + | otherwise = Inr <$> genericToEnum' (n - ca) + genericFromEnum' = case _ of + Inl a -> genericFromEnum' a + Inr b -> genericFromEnum' b + unwrap (genericCardinality' :: Cardinality a) + +-- | A `Generic` implementation of the `cardinality` member from the +-- | `BoundedEnum` type class. +genericCardinality :: forall a rep. Generic a rep => GenericBoundedEnum rep => Cardinality a +genericCardinality = Cardinality (unwrap (genericCardinality' :: Cardinality rep)) + +-- | A `Generic` implementation of the `toEnum` member from the `BoundedEnum` +-- | type class. +genericToEnum :: forall a rep. Generic a rep => GenericBoundedEnum rep => Int -> Maybe a +genericToEnum = map to <<< genericToEnum' + +-- | A `Generic` implementation of the `fromEnum` member from the `BoundedEnum` +-- | type class. +genericFromEnum :: forall a rep. Generic a rep => GenericBoundedEnum rep => a -> Int +genericFromEnum = genericFromEnum' <<< from From 530077098b5bf0789992ed5817f9b661a2495d24 Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Sat, 5 Aug 2017 16:14:34 +0100 Subject: [PATCH 10/30] Add enum tests, convert existing "tests" into assertions --- test/Main.purs | 105 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/test/Main.purs b/test/Main.purs index d661c9b..662bf81 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -1,13 +1,18 @@ module Test.Main where import Prelude + import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Console (CONSOLE, logShow) +import Control.Monad.Eff.Console (CONSOLE, log, logShow) +import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum) import Data.Generic.Rep as G +import Data.Generic.Rep.Bounded as GBounded +import Data.Generic.Rep.Enum as GEnum import Data.Generic.Rep.Eq as GEq import Data.Generic.Rep.Ord as GOrd import Data.Generic.Rep.Show as GShow -import Data.Generic.Rep.Bounded as GBounded +import Data.Maybe (Maybe(..)) +import Test.Assert (ASSERT, assert) data List a = Nil | Cons { head :: a, tail :: List a } @@ -36,16 +41,98 @@ instance showSimpleBounded :: Show SimpleBounded where instance boundedSimpleBounded :: Bounded SimpleBounded where bottom = GBounded.genericBottom top = GBounded.genericTop +instance enumSimpleBounded :: Enum SimpleBounded where + pred = GEnum.genericPred + succ = GEnum.genericSucc +instance boundedEnumSimpleBounded :: BoundedEnum SimpleBounded where + cardinality = GEnum.genericCardinality + toEnum = GEnum.genericToEnum + fromEnum = GEnum.genericFromEnum + +data Option a = None | Some a +derive instance genericOption :: G.Generic (Option a) _ +instance eqOption :: Eq a => Eq (Option a) where + eq x y = GEq.genericEq x y +instance ordOption :: Ord a => Ord (Option a) where + compare x y = GOrd.genericCompare x y +instance showOption :: Show a => Show (Option a) where + show x = GShow.genericShow x +instance boundedOption :: Bounded a => Bounded (Option a) where + bottom = GBounded.genericBottom + top = GBounded.genericTop +instance enumOption :: (Bounded a, Enum a) => Enum (Option a) where + pred = GEnum.genericPred + succ = GEnum.genericSucc +instance boundedEnumOption :: BoundedEnum a => BoundedEnum (Option a) where + cardinality = GEnum.genericCardinality + toEnum = GEnum.genericToEnum + fromEnum = GEnum.genericFromEnum -main :: Eff (console :: CONSOLE) Unit +main :: Eff (console :: CONSOLE, assert :: ASSERT) Unit main = do logShow (cons 1 (cons 2 Nil)) - logShow (cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil)) - logShow (cons 1 (cons 2 Nil) == cons 1 Nil) + log "Checking equality" + assert $ cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil) + + log "Checking inequality" + assert $ cons 1 (cons 2 Nil) /= cons 1 Nil + + log "Checking comparison EQ" + assert $ (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil)) == EQ + + log "Checking comparison GT" + assert $ (cons 1 (cons 2 Nil) `compare` cons 1 Nil) == GT + + log "Checking comparison LT" + assert $ (cons 1 Nil `compare` cons 1 (cons 2 Nil)) == LT + + log "Checking simple bottom" + assert $ bottom == A + + log "Checking simple top" + assert $ top == D + + log "Checking composite bottom" + assert $ bottom == None :: Option SimpleBounded + + log "Checking composite top" + assert $ top == Some D + + log "Checking simple pred bottom" + assert $ pred (bottom :: SimpleBounded) == Nothing + + log "Checking simple (pred =<< succ bottom)" + assert $ (pred =<< succ bottom) == Just A + + log "Checking simple succ top" + assert $ succ (top :: SimpleBounded) == Nothing + + log "Checking simple (succ =<< pred top)" + assert $ (succ =<< pred top) == Just D + + log "Checking composite pred bottom" + assert $ pred (bottom :: Option SimpleBounded) == Nothing + + log "Checking composite (pred =<< succ bottom)" + assert $ (pred =<< succ (bottom :: Option SimpleBounded)) == Just None + + log "Checking composite succ top" + assert $ succ (top :: Option SimpleBounded) == Nothing + + log "Checking composite (succ =<< pred top)" + assert $ (succ =<< pred top) == Just (Some D) + + log "Checking simple cardinality" + assert $ (cardinality :: Cardinality SimpleBounded) == Cardinality 4 + + log "Checking composite cardinality" + assert $ (cardinality :: Cardinality (Option SimpleBounded)) == Cardinality 5 - logShow (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil)) - logShow (cons 1 (cons 2 Nil) `compare` cons 1 Nil) + log "Checking simple toEnum/fromEnum roundtrip" + assert $ toEnum (fromEnum A) == Just A + assert $ toEnum (fromEnum B) == Just B - logShow (bottom :: SimpleBounded) - logShow (top :: SimpleBounded) + log "Checking composite toEnum/fromEnum roundtrip" + assert $ toEnum (fromEnum (None :: Option SimpleBounded)) == Just (None :: Option SimpleBounded) + assert $ toEnum (fromEnum (Some A)) == Just (Some A) From b31a5ec81a87a6f215ec1e54e236e81e7e8ea007 Mon Sep 17 00:00:00 2001 From: Jorge Acereda Date: Thu, 31 Aug 2017 18:30:03 +0200 Subject: [PATCH 11/30] Product instances in Bounded and Enum --- src/Data/Generic/Rep/Bounded.purs | 6 +++ src/Data/Generic/Rep/Enum.purs | 25 +++++++++++- test/Main.purs | 66 ++++++++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/Data/Generic/Rep/Bounded.purs b/src/Data/Generic/Rep/Bounded.purs index 9ba33e3..8b1ec85 100644 --- a/src/Data/Generic/Rep/Bounded.purs +++ b/src/Data/Generic/Rep/Bounded.purs @@ -23,6 +23,9 @@ instance genericBottomArgument :: Bounded a => GenericBottom (Argument a) where instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where genericBottom' = Inl genericBottom' +instance genericBottomProduct :: (GenericBottom a, GenericBottom b) => GenericBottom (Product a b) where + genericBottom' = Product genericBottom' genericBottom' + instance genericBottomConstructor :: GenericBottom a => GenericBottom (Constructor name a) where genericBottom' = Constructor genericBottom' @@ -38,6 +41,9 @@ instance genericTopArgument :: Bounded a => GenericTop (Argument a) where instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where genericTop' = Inr genericTop' +instance genericTopProduct :: (GenericTop a, GenericTop b) => GenericTop (Product a b) where + genericTop' = Product genericTop' genericTop' + instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a) where genericTop' = Constructor genericTop' diff --git a/src/Data/Generic/Rep/Enum.purs b/src/Data/Generic/Rep/Enum.purs index 767cacd..594729c 100644 --- a/src/Data/Generic/Rep/Enum.purs +++ b/src/Data/Generic/Rep/Enum.purs @@ -3,7 +3,7 @@ module Data.Generic.Rep.Enum where import Prelude import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum) -import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Sum(..), from, to) +import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), Sum(..), from, to) import Data.Generic.Rep.Bounded (class GenericBottom, class GenericTop, genericBottom', genericTop') import Data.Maybe (Maybe(..)) import Data.Newtype (unwrap) @@ -36,6 +36,15 @@ instance genericEnumSum :: (GenericEnum a, GenericTop a, GenericEnum b, GenericB Just a' -> Just (Inl a') Inr b -> Inr <$> genericSucc' b +instance genericEnumProduct :: (GenericEnum a, GenericTop a, GenericBottom a, GenericEnum b, GenericTop b, GenericBottom b) => GenericEnum (Product a b) where + genericPred' (Product a b) = case genericPred' b of + Just p -> Just $ Product a p + Nothing -> flip Product genericTop' <$> genericPred' a + genericSucc' (Product a b) = case genericSucc' b of + Just s -> Just $ Product a s + Nothing -> flip Product genericBottom' <$> genericSucc' a + + -- | A `Generic` implementation of the `pred` member from the `Enum` type class. genericPred :: forall a rep. Generic a rep => GenericEnum rep => a -> Maybe a genericPred = map to <<< genericPred' <<< from @@ -79,6 +88,20 @@ instance genericBoundedEnumSum :: (GenericBoundedEnum a, GenericBoundedEnum b) = Inl a -> genericFromEnum' a Inr b -> genericFromEnum' b + unwrap (genericCardinality' :: Cardinality a) + +instance genericBoundedEnumProduct :: (GenericBoundedEnum a, GenericBoundedEnum b) => GenericBoundedEnum (Product a b) where + genericCardinality' = + Cardinality + $ unwrap (genericCardinality' :: Cardinality a) + * unwrap (genericCardinality' :: Cardinality b) + genericToEnum' n = to genericCardinality' + where to :: Cardinality b -> Maybe (Product a b) + to (Cardinality cb) = Product <$> (genericToEnum' $ n `div` cb) <*> (genericToEnum' $ n `mod` cb) + genericFromEnum' = from genericCardinality' + where from :: Cardinality b -> (Product a b) -> Int + from (Cardinality cb) (Product a b) = genericFromEnum' a * cb + genericFromEnum' b + + -- | A `Generic` implementation of the `cardinality` member from the -- | `BoundedEnum` type class. genericCardinality :: forall a rep. Generic a rep => GenericBoundedEnum rep => Cardinality a diff --git a/test/Main.purs b/test/Main.purs index 662bf81..2dc987b 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -4,7 +4,7 @@ import Prelude import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log, logShow) -import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum) +import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum, enumFromTo) import Data.Generic.Rep as G import Data.Generic.Rep.Bounded as GBounded import Data.Generic.Rep.Enum as GEnum @@ -68,6 +68,45 @@ instance boundedEnumOption :: BoundedEnum a => BoundedEnum (Option a) where toEnum = GEnum.genericToEnum fromEnum = GEnum.genericFromEnum +data Bit = Zero | One +derive instance genericBit :: G.Generic Bit _ +instance eqBit :: Eq Bit where + eq x y = GEq.genericEq x y +instance ordBit :: Ord Bit where + compare x y = GOrd.genericCompare x y +instance showBit :: Show Bit where + show x = GShow.genericShow x +instance boundedBit :: Bounded Bit where + bottom = GBounded.genericBottom + top = GBounded.genericTop +instance enumBit :: Enum Bit where + pred = GEnum.genericPred + succ = GEnum.genericSucc +instance boundedEnumBit :: BoundedEnum Bit where + cardinality = GEnum.genericCardinality + toEnum = GEnum.genericToEnum + fromEnum = GEnum.genericFromEnum + +data Pair a b = Pair a b +derive instance genericPair :: G.Generic (Pair a b) _ +instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where + eq = GEq.genericEq +instance ordPair :: (Ord a, Ord b) => Ord (Pair a b) where + compare = GOrd.genericCompare +instance showPair :: (Show a, Show b) => Show (Pair a b) where + show = GShow.genericShow +instance boundedPair :: (Bounded a, Bounded b) => Bounded (Pair a b) where + bottom = GBounded.genericBottom + top = GBounded.genericTop +instance enumPair :: (Bounded a, Enum a, Bounded b, Enum b) => Enum (Pair a b) where + pred = GEnum.genericPred + succ = GEnum.genericSucc +instance boundedEnumPair :: (BoundedEnum a, BoundedEnum b) => BoundedEnum (Pair a b) where + cardinality = GEnum.genericCardinality + toEnum = GEnum.genericToEnum + fromEnum = GEnum.genericFromEnum + + main :: Eff (console :: CONSOLE, assert :: ASSERT) Unit main = do logShow (cons 1 (cons 2 Nil)) @@ -99,6 +138,12 @@ main = do log "Checking composite top" assert $ top == Some D + log "Checking product bottom" + assert $ bottom == Pair Zero A :: Pair Bit SimpleBounded + + log "Checking product top" + assert $ top == Pair One D :: Pair Bit SimpleBounded + log "Checking simple pred bottom" assert $ pred (bottom :: SimpleBounded) == Nothing @@ -123,12 +168,27 @@ main = do log "Checking composite (succ =<< pred top)" assert $ (succ =<< pred top) == Just (Some D) + log "Checking product pred bottom" + assert $ pred (bottom :: Pair Bit SimpleBounded) == Nothing + + log "Checking product (pred =<< succ bottom)" + assert $ (pred =<< succ (bottom :: Pair Bit SimpleBounded)) == Just (Pair Zero A) + + log "Checking product succ top" + assert $ succ (top :: Pair Bit SimpleBounded) == Nothing + + log "Checking product (succ =<< pred top)" + assert $ (succ =<< pred top) == Just (Pair One D) + log "Checking simple cardinality" assert $ (cardinality :: Cardinality SimpleBounded) == Cardinality 4 log "Checking composite cardinality" assert $ (cardinality :: Cardinality (Option SimpleBounded)) == Cardinality 5 + log "Checking product cardinality" + assert $ (cardinality :: Cardinality (Pair Bit SimpleBounded)) == Cardinality 8 + log "Checking simple toEnum/fromEnum roundtrip" assert $ toEnum (fromEnum A) == Just A assert $ toEnum (fromEnum B) == Just B @@ -136,3 +196,7 @@ main = do log "Checking composite toEnum/fromEnum roundtrip" assert $ toEnum (fromEnum (None :: Option SimpleBounded)) == Just (None :: Option SimpleBounded) assert $ toEnum (fromEnum (Some A)) == Just (Some A) + + log "Checking product toEnum/fromEnum roundtrip" + assert $ let allPairs = enumFromTo bottom top :: Array (Pair Bit SimpleBounded) + in toEnum <<< fromEnum <$> allPairs == Just <$> allPairs From 5fc435bb4bc6d047981ad60f322c69fe01d53c44 Mon Sep 17 00:00:00 2001 From: Kristoffer Josefsson Date: Mon, 4 Dec 2017 13:04:04 -0500 Subject: [PATCH 12/30] Added GenericShowFields instances for NoConstructors and NoArguments (#20) * Added Eq and Show instances to NoArguments and NoConstructors * Added GenericShowFields * Removed Show, Eq * Cleanup * Removed NoConstructors Show instance --- src/Data/Generic/Rep/Show.purs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs index edd233d..9b64ff0 100644 --- a/src/Data/Generic/Rep/Show.purs +++ b/src/Data/Generic/Rep/Show.purs @@ -65,6 +65,9 @@ instance genericShowFieldsField genericShowFields (Field a) = [reflectSymbol (SProxy :: SProxy name) <> ": " <> show a] +instance genericShowFieldsNoArguments :: GenericShowFields NoArguments where + genericShowFields _ = [] + -- | A `Generic` implementation of the `show` member from the `Show` type class. genericShow :: forall a rep. Generic a rep => GenericShow rep => a -> String genericShow x = genericShow' (from x) From 9bbb4463724d75905475ab112b5ee1ab3ae737eb Mon Sep 17 00:00:00 2001 From: Liam Goodacre Date: Wed, 11 Apr 2018 22:41:34 +0100 Subject: [PATCH 13/30] Remove Rec and Field & update package & bower symbols --- src/Data/Generic/Rep.purs | 9 --------- src/Data/Generic/Rep/Eq.purs | 6 ------ src/Data/Generic/Rep/Monoid.purs | 6 ------ src/Data/Generic/Rep/Ord.purs | 6 ------ src/Data/Generic/Rep/Semigroup.purs | 6 ------ src/Data/Generic/Rep/Show.purs | 22 ---------------------- 6 files changed, 55 deletions(-) diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs index 9f1c47f..92bf845 100644 --- a/src/Data/Generic/Rep.purs +++ b/src/Data/Generic/Rep.purs @@ -8,8 +8,6 @@ module Data.Generic.Rep , Product(..) , Constructor(..) , Argument(..) - , Rec(..) - , Field(..) ) where import Data.Maybe (Maybe(..)) @@ -33,13 +31,6 @@ newtype Constructor (name :: Symbol) a = Constructor a -- | A representation for an argument in a data constructor. newtype Argument a = Argument a --- | A representation for records. -newtype Rec fields = Rec fields - --- | A representation for a record field which includes the field name --- | as a type-level string. -newtype Field (field :: Symbol) a = Field a - -- | The `Generic` class asserts the existence of a type function from types -- | to their representations using the type constructors defined in this module. class Generic a rep | a -> rep where diff --git a/src/Data/Generic/Rep/Eq.purs b/src/Data/Generic/Rep/Eq.purs index 09a9ff5..fe09ab0 100644 --- a/src/Data/Generic/Rep/Eq.purs +++ b/src/Data/Generic/Rep/Eq.purs @@ -30,12 +30,6 @@ instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) w instance genericEqArgument :: Eq a => GenericEq (Argument a) where genericEq' (Argument a1) (Argument a2) = a1 == a2 -instance genericEqRec :: GenericEq a => GenericEq (Rec a) where - genericEq' (Rec a1) (Rec a2) = genericEq' a1 a2 - -instance genericEqField :: Eq a => GenericEq (Field name a) where - genericEq' (Field a1) (Field a2) = a1 == a2 - -- | A `Generic` implementation of the `eq` member from the `Eq` type class. genericEq :: forall a rep. Generic a rep => GenericEq rep => a -> a -> Boolean genericEq x y = genericEq' (from x) (from y) diff --git a/src/Data/Generic/Rep/Monoid.purs b/src/Data/Generic/Rep/Monoid.purs index d2ceddf..999b2f5 100644 --- a/src/Data/Generic/Rep/Monoid.purs +++ b/src/Data/Generic/Rep/Monoid.purs @@ -22,12 +22,6 @@ instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Construct instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where genericMempty' = Argument mempty -instance genericMonoidRec :: GenericMonoid a => GenericMonoid (Rec a) where - genericMempty' = Rec genericMempty' - -instance genericMonoidField :: Monoid a => GenericMonoid (Field name a) where - genericMempty' = Field mempty - -- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. genericMempty :: forall a rep. Generic a rep => GenericMonoid rep => a genericMempty = to genericMempty' diff --git a/src/Data/Generic/Rep/Ord.purs b/src/Data/Generic/Rep/Ord.purs index 0136f21..ad7c45c 100644 --- a/src/Data/Generic/Rep/Ord.purs +++ b/src/Data/Generic/Rep/Ord.purs @@ -34,12 +34,6 @@ instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where genericCompare' (Argument a1) (Argument a2) = compare a1 a2 -instance genericOrdRec :: GenericOrd a => GenericOrd (Rec a) where - genericCompare' (Rec a1) (Rec a2) = genericCompare' a1 a2 - -instance genericOrdField :: Ord a => GenericOrd (Field name a) where - genericCompare' (Field a1) (Field a2) = compare a1 a2 - -- | A `Generic` implementation of the `compare` member from the `Ord` type class. genericCompare :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering genericCompare x y = genericCompare' (from x) (from y) diff --git a/src/Data/Generic/Rep/Semigroup.purs b/src/Data/Generic/Rep/Semigroup.purs index e36e572..1ab5606 100644 --- a/src/Data/Generic/Rep/Semigroup.purs +++ b/src/Data/Generic/Rep/Semigroup.purs @@ -26,12 +26,6 @@ instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup ( instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) -instance genericSemigroupRec :: GenericSemigroup a => GenericSemigroup (Rec a) where - genericAppend' (Rec a1) (Rec a2) = Rec (genericAppend' a1 a2) - -instance genericSemigroupField :: Semigroup a => GenericSemigroup (Field name a) where - genericAppend' (Field a1) (Field a2) = Field (append a1 a2) - -- | A `Generic` implementation of the `append` member from the `Semigroup` type class. genericAppend :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a genericAppend x y = to (genericAppend' (from x) (from y)) diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs index 9b64ff0..f7be702 100644 --- a/src/Data/Generic/Rep/Show.purs +++ b/src/Data/Generic/Rep/Show.purs @@ -4,8 +4,6 @@ module Data.Generic.Rep.Show , genericShow , class GenericShowArgs , genericShowArgs - , class GenericShowFields - , genericShowFields ) where import Prelude (class Show, show, (<>)) @@ -19,9 +17,6 @@ class GenericShow a where class GenericShowArgs a where genericShowArgs :: a -> Array String -class GenericShowFields a where - genericShowFields :: a -> Array String - instance genericShowNoConstructors :: GenericShow NoConstructors where genericShow' a = genericShow' a @@ -37,11 +32,6 @@ instance genericShowArgsProduct => GenericShowArgs (Product a b) where genericShowArgs (Product a b) = genericShowArgs a <> genericShowArgs b -instance genericShowFieldsProduct - :: (GenericShowFields a, GenericShowFields b) - => GenericShowFields (Product a b) where - genericShowFields (Product a b) = genericShowFields a <> genericShowFields b - instance genericShowConstructor :: (GenericShowArgs a, IsSymbol name) => GenericShow (Constructor name a) where @@ -56,18 +46,6 @@ instance genericShowConstructor instance genericShowArgsArgument :: Show a => GenericShowArgs (Argument a) where genericShowArgs (Argument a) = [show a] -instance genericShowArgsRec :: GenericShowFields a => GenericShowArgs (Rec a) where - genericShowArgs (Rec a) = ["{ " <> intercalate ", " (genericShowFields a) <> " }"] - -instance genericShowFieldsField - :: (Show a, IsSymbol name) - => GenericShowFields (Field name a) where - genericShowFields (Field a) = - [reflectSymbol (SProxy :: SProxy name) <> ": " <> show a] - -instance genericShowFieldsNoArguments :: GenericShowFields NoArguments where - genericShowFields _ = [] - -- | A `Generic` implementation of the `show` member from the `Show` type class. genericShow :: forall a rep. Generic a rep => GenericShow rep => a -> String genericShow x = genericShow' (from x) From b9f0eec32ed35b71ca3e006a250ee140e2231f8f Mon Sep 17 00:00:00 2001 From: Liam Goodacre Date: Thu, 19 Apr 2018 12:19:40 +0100 Subject: [PATCH 14/30] Bump deps for compiler/0.12 --- test/Main.purs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/Main.purs b/test/Main.purs index 2dc987b..1892da3 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -2,8 +2,8 @@ module Test.Main where import Prelude -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Console (CONSOLE, log, logShow) +import Effect (Effect) +import Effect.Console (log, logShow) import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum, enumFromTo) import Data.Generic.Rep as G import Data.Generic.Rep.Bounded as GBounded @@ -12,7 +12,7 @@ import Data.Generic.Rep.Eq as GEq import Data.Generic.Rep.Ord as GOrd import Data.Generic.Rep.Show as GShow import Data.Maybe (Maybe(..)) -import Test.Assert (ASSERT, assert) +import Test.Assert (assert) data List a = Nil | Cons { head :: a, tail :: List a } @@ -105,9 +105,8 @@ instance boundedEnumPair :: (BoundedEnum a, BoundedEnum b) => BoundedEnum (Pair cardinality = GEnum.genericCardinality toEnum = GEnum.genericToEnum fromEnum = GEnum.genericFromEnum - -main :: Eff (console :: CONSOLE, assert :: ASSERT) Unit +main :: Effect Unit main = do logShow (cons 1 (cons 2 Nil)) From bc43932f72883a7e4cb763804622d4076f4894a7 Mon Sep 17 00:00:00 2001 From: Liam Goodacre Date: Wed, 25 Apr 2018 21:36:38 +0100 Subject: [PATCH 15/30] Remove symbols and fix operator fixity issue --- test/Main.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Main.purs b/test/Main.purs index 1892da3..78d5e51 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -198,4 +198,4 @@ main = do log "Checking product toEnum/fromEnum roundtrip" assert $ let allPairs = enumFromTo bottom top :: Array (Pair Bit SimpleBounded) - in toEnum <<< fromEnum <$> allPairs == Just <$> allPairs + in (toEnum <<< fromEnum <$> allPairs) == (Just <$> allPairs) From 0dcffa83251ad1eef725f316f98d558c081a7f55 Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Wed, 23 May 2018 21:14:04 +0100 Subject: [PATCH 16/30] Update dependencies, license --- test/Main.purs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/Main.purs b/test/Main.purs index 78d5e51..5d1b5f6 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -24,9 +24,6 @@ derive instance genericList :: G.Generic (List a) _ instance eqList :: Eq a => Eq (List a) where eq x y = GEq.genericEq x y -instance ordList :: Ord a => Ord (List a) where - compare x y = GOrd.genericCompare x y - instance showList :: Show a => Show (List a) where show x = GShow.genericShow x @@ -117,13 +114,13 @@ main = do assert $ cons 1 (cons 2 Nil) /= cons 1 Nil log "Checking comparison EQ" - assert $ (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil)) == EQ + assert $ (Pair Zero (Some One) `compare` Pair Zero (Some One)) == EQ log "Checking comparison GT" - assert $ (cons 1 (cons 2 Nil) `compare` cons 1 Nil) == GT + assert $ (Pair (Some One) Zero `compare` Pair (Some Zero) Zero) == GT log "Checking comparison LT" - assert $ (cons 1 Nil `compare` cons 1 (cons 2 Nil)) == LT + assert $ (Pair Zero One `compare` Pair One One) == LT log "Checking simple bottom" assert $ bottom == A From c564620679f50d3950eff2782f5c6796d144dff8 Mon Sep 17 00:00:00 2001 From: Denis Stoyanov Date: Mon, 30 Jul 2018 21:05:07 +0300 Subject: [PATCH 17/30] Added HeytingAlgebra, Semiring, Ring --- src/Data/Generic/Rep/HeytingAlgebra.purs | 70 ++++++++++++++++++++++++ src/Data/Generic/Rep/Ring.purs | 24 ++++++++ src/Data/Generic/Rep/Semiring.purs | 51 +++++++++++++++++ test/Main.purs | 69 ++++++++++++++++++++++- 4 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 src/Data/Generic/Rep/HeytingAlgebra.purs create mode 100644 src/Data/Generic/Rep/Ring.purs create mode 100644 src/Data/Generic/Rep/Semiring.purs diff --git a/src/Data/Generic/Rep/HeytingAlgebra.purs b/src/Data/Generic/Rep/HeytingAlgebra.purs new file mode 100644 index 0000000..f2223d8 --- /dev/null +++ b/src/Data/Generic/Rep/HeytingAlgebra.purs @@ -0,0 +1,70 @@ +module Data.Generic.Rep.HeytingAlgebra where + +import Prelude + +import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) +import Data.HeytingAlgebra (ff, implies, tt) + +class GenericHeytingAlgebra a where + genericFF' :: a + genericTT' :: a + genericImplies' :: a -> a -> a + genericConj' :: a -> a -> a + genericDisj' :: a -> a -> a + genericNot' :: a -> a + +instance genericHeytingAlgebraNoArguments :: GenericHeytingAlgebra NoArguments where + genericFF' = NoArguments + genericTT' = NoArguments + genericImplies' _ _ = NoArguments + genericConj' _ _ = NoArguments + genericDisj' _ _ = NoArguments + genericNot' _ = NoArguments + +instance genericHeytingAlgebraArgument :: HeytingAlgebra a => GenericHeytingAlgebra (Argument a) where + genericFF' = Argument ff + genericTT' = Argument tt + genericImplies' (Argument x) (Argument y) = Argument (implies x y) + genericConj' (Argument x) (Argument y) = Argument (conj x y) + genericDisj' (Argument x) (Argument y) = Argument (disj x y) + genericNot' (Argument x) = Argument (not x) + +instance genericHeytingAlgebraProduct :: (GenericHeytingAlgebra a, GenericHeytingAlgebra b) => GenericHeytingAlgebra (Product a b) where + genericFF' = Product genericFF' genericFF' + genericTT' = Product genericTT' genericTT' + genericImplies' (Product a1 b1) (Product a2 b2) = Product (genericImplies' a1 a2) (genericImplies' b1 b2) + genericConj' (Product a1 b1) (Product a2 b2) = Product (genericConj' a1 a2) (genericConj' b1 b2) + genericDisj' (Product a1 b1) (Product a2 b2) = Product (genericDisj' a1 a2) (genericDisj' b1 b2) + genericNot' (Product a b) = Product (genericNot' a) (genericNot' b) + +instance genericHeytingAlgebraConstructor :: GenericHeytingAlgebra a => GenericHeytingAlgebra (Constructor name a) where + genericFF' = Constructor genericFF' + genericTT' = Constructor genericTT' + genericImplies' (Constructor a1) (Constructor a2) = Constructor (genericImplies' a1 a2) + genericConj' (Constructor a1) (Constructor a2) = Constructor (genericConj' a1 a2) + genericDisj' (Constructor a1) (Constructor a2) = Constructor (genericDisj' a1 a2) + genericNot' (Constructor a) = Constructor (genericNot' a) + +-- | A `Generic` implementation of the `ff` member from the `HeytingAlgebra` type class. +genericFF :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a +genericFF = to genericFF' + +-- | A `Generic` implementation of the `tt` member from the `HeytingAlgebra` type class. +genericTT :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a +genericTT = to genericTT' + +-- | A `Generic` implementation of the `implies` member from the `HeytingAlgebra` type class. +genericImplies :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericImplies x y = to $ from x `genericImplies'` from y + +-- | A `Generic` implementation of the `conj` member from the `HeytingAlgebra` type class. +genericConj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericConj x y = to $ from x `genericConj'` from y + +-- | A `Generic` implementation of the `disj` member from the `HeytingAlgebra` type class. +genericDisj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a +genericDisj x y = to $ from x `genericDisj'` from y + +-- | A `Generic` implementation of the `not` member from the `HeytingAlgebra` type class. +genericNot :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a +genericNot x = to $ genericNot' (from x) \ No newline at end of file diff --git a/src/Data/Generic/Rep/Ring.purs b/src/Data/Generic/Rep/Ring.purs new file mode 100644 index 0000000..f5c73f3 --- /dev/null +++ b/src/Data/Generic/Rep/Ring.purs @@ -0,0 +1,24 @@ +module Data.Generic.Rep.Ring where + +import Prelude + +import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) + +class GenericRing a where + genericSub' :: a -> a -> a + +instance genericRingNoArguments :: GenericRing NoArguments where + genericSub' _ _ = NoArguments + +instance genericRingArgument :: Ring a => GenericRing (Argument a) where + genericSub' (Argument x) (Argument y) = Argument (sub x y) + +instance genericRingProduct :: (GenericRing a, GenericRing b) => GenericRing (Product a b) where + genericSub' (Product a1 b1) (Product a2 b2) = Product (genericSub' a1 a2) (genericSub' b1 b2) + +instance genericRingConstructor :: GenericRing a => GenericRing (Constructor name a) where + genericSub' (Constructor a1) (Constructor a2) = Constructor (genericSub' a1 a2) + +-- | A `Generic` implementation of the `sub` member from the `Ring` type class. +genericSub :: forall a rep. Generic a rep => GenericRing rep => a -> a -> a +genericSub x y = to $ from x `genericSub'` from y \ No newline at end of file diff --git a/src/Data/Generic/Rep/Semiring.purs b/src/Data/Generic/Rep/Semiring.purs new file mode 100644 index 0000000..b6b2412 --- /dev/null +++ b/src/Data/Generic/Rep/Semiring.purs @@ -0,0 +1,51 @@ +module Data.Generic.Rep.Semiring where + +import Prelude + +import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) + +class GenericSemiring a where + genericAdd' :: a -> a -> a + genericZero' :: a + genericMul' :: a -> a -> a + genericOne' :: a + +instance genericSemiringNoArguments :: GenericSemiring NoArguments where + genericAdd' _ _ = NoArguments + genericZero' = NoArguments + genericMul' _ _ = NoArguments + genericOne' = NoArguments + +instance genericSemiringArgument :: Semiring a => GenericSemiring (Argument a) where + genericAdd' (Argument x) (Argument y) = Argument (add x y) + genericZero' = Argument zero + genericMul' (Argument x) (Argument y) = Argument (mul x y) + genericOne' = Argument one + +instance genericSemiringProduct :: (GenericSemiring a, GenericSemiring b) => GenericSemiring (Product a b) where + genericAdd' (Product a1 b1) (Product a2 b2) = Product (genericAdd' a1 a2) (genericAdd' b1 b2) + genericZero' = Product genericZero' genericZero' + genericMul' (Product a1 b1) (Product a2 b2) = Product (genericMul' a1 a2) (genericMul' b1 b2) + genericOne' = Product genericOne' genericOne' + +instance genericSemiringConstructor :: GenericSemiring a => GenericSemiring (Constructor name a) where + genericAdd' (Constructor a1) (Constructor a2) = Constructor (genericAdd' a1 a2) + genericZero' = Constructor genericZero' + genericMul' (Constructor a1) (Constructor a2) = Constructor (genericMul' a1 a2) + genericOne' = Constructor genericOne' + +-- | A `Generic` implementation of the `zero` member from the `Semiring` type class. +genericZero :: forall a rep. Generic a rep => GenericSemiring rep => a +genericZero = to genericZero' + +-- | A `Generic` implementation of the `one` member from the `Semiring` type class. +genericOne :: forall a rep. Generic a rep => GenericSemiring rep => a +genericOne = to genericOne' + +-- | A `Generic` implementation of the `add` member from the `Semiring` type class. +genericAdd :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a +genericAdd x y = to $ from x `genericAdd'` from y + +-- | A `Generic` implementation of the `mul` member from the `Semiring` type class. +genericMul :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a +genericMul x y = to $ from x `genericMul'` from y \ No newline at end of file diff --git a/test/Main.purs b/test/Main.purs index 5d1b5f6..085e727 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -2,16 +2,21 @@ module Test.Main where import Prelude -import Effect (Effect) -import Effect.Console (log, logShow) import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum, enumFromTo) import Data.Generic.Rep as G import Data.Generic.Rep.Bounded as GBounded import Data.Generic.Rep.Enum as GEnum import Data.Generic.Rep.Eq as GEq +import Data.Generic.Rep.HeytingAlgebra as GHeytingAlgebra import Data.Generic.Rep.Ord as GOrd +import Data.Generic.Rep.Ring as GRing +import Data.Generic.Rep.Semiring as GSemiring import Data.Generic.Rep.Show as GShow +import Data.HeytingAlgebra (ff, tt) import Data.Maybe (Maybe(..)) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Console (log, logShow) import Test.Assert (assert) data List a = Nil | Cons { head :: a, tail :: List a } @@ -103,6 +108,36 @@ instance boundedEnumPair :: (BoundedEnum a, BoundedEnum b) => BoundedEnum (Pair toEnum = GEnum.genericToEnum fromEnum = GEnum.genericFromEnum +data A1 = A1 (Tuple (Tuple Int {a :: Int}) {a :: Int}) +derive instance genericA1 :: G.Generic A1 _ +instance eqA1 :: Eq A1 where + eq a = GEq.genericEq a +instance showA1 :: Show A1 where + show a = GShow.genericShow a +instance semiringA1 :: Semiring A1 where + zero = GSemiring.genericZero + one = GSemiring.genericOne + add x y = GSemiring.genericAdd x y + mul x y = GSemiring.genericMul x y +instance ringA1 :: Ring A1 where + sub x y = GRing.genericSub x y + +data B1 = B1 (Tuple (Tuple Boolean {a :: Boolean}) {a :: Boolean}) +derive instance genericB1 :: G.Generic B1 _ +instance eqB1 :: Eq B1 where + eq a = GEq.genericEq a +instance showB1 :: Show B1 where + show a = GShow.genericShow a +instance heytingAlgebraB1 :: HeytingAlgebra B1 where + ff = GHeytingAlgebra.genericFF + tt = GHeytingAlgebra.genericTT + implies x y = GHeytingAlgebra.genericImplies x y + conj x y = GHeytingAlgebra.genericConj x y + disj x y = GHeytingAlgebra.genericDisj x y + not x = GHeytingAlgebra.genericNot x + +instance booleanAlgebraB1 :: BooleanAlgebra B1 + main :: Effect Unit main = do logShow (cons 1 (cons 2 Nil)) @@ -196,3 +231,33 @@ main = do log "Checking product toEnum/fromEnum roundtrip" assert $ let allPairs = enumFromTo bottom top :: Array (Pair Bit SimpleBounded) in (toEnum <<< fromEnum <$> allPairs) == (Just <$> allPairs) + + log "Checking zero" + assert $ (zero :: A1) == A1 (Tuple (Tuple 0 {a: 0}) {a: 0}) + + log "Checking one" + assert $ (one :: A1) == A1 (Tuple (Tuple 1 {a: 1}) {a: 1}) + + log "Checking add" + assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) + A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 150 {a: 40}) {a: 60}) + + log "Checking mul" + assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) * A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 5000 {a: 300}) {a: 800}) + + log "Checking sub" + assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) - A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 50 {a: -20}) {a: -20}) + + log "Checking ff" + assert $ (ff :: B1) == B1 (Tuple (Tuple false {a: false}) {a: false}) + + log "Checking tt" + assert $ (tt :: B1) == B1 (Tuple (Tuple true {a: true}) {a: true}) + + log "Checking conj" + assert $ (B1 (Tuple (Tuple true {a: false}) {a: true}) && B1 (Tuple (Tuple false {a: false}) {a: true})) == B1 (Tuple (Tuple false { a: false }) { a: true }) + + log "Checking disj" + assert $ (B1 (Tuple (Tuple true {a: false}) {a: true}) || B1 (Tuple (Tuple false {a: false}) {a: true})) == B1 (Tuple (Tuple true { a: false }) { a: true }) + + log "Checking not" + assert $ not B1 (Tuple (Tuple true {a: false}) {a: true}) == B1 (Tuple (Tuple false {a: true}) {a: false}) \ No newline at end of file From 952627c72cc42f171f71610edd18a030d3c41bf5 Mon Sep 17 00:00:00 2001 From: Gary Burgess Date: Mon, 27 Apr 2020 17:47:57 +0100 Subject: [PATCH 18/30] Fix type annotation precedence in tests --- test/Main.purs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Main.purs b/test/Main.purs index 085e727..4ae7f7d 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -164,16 +164,16 @@ main = do assert $ top == D log "Checking composite bottom" - assert $ bottom == None :: Option SimpleBounded + assert $ bottom == (None :: Option SimpleBounded) log "Checking composite top" assert $ top == Some D log "Checking product bottom" - assert $ bottom == Pair Zero A :: Pair Bit SimpleBounded + assert $ bottom == (Pair Zero A :: Pair Bit SimpleBounded) log "Checking product top" - assert $ top == Pair One D :: Pair Bit SimpleBounded + assert $ top == (Pair One D :: Pair Bit SimpleBounded) log "Checking simple pred bottom" assert $ pred (bottom :: SimpleBounded) == Nothing From f7f498b56a31c29f2c7ba01c12e6a6969f73f536 Mon Sep 17 00:00:00 2001 From: Cyril Date: Wed, 25 Nov 2020 07:30:02 +0100 Subject: [PATCH 19/30] Replace monomorphic proxies by Type.Proxy.Proxy (#44) --- src/Data/Generic/Rep/Show.purs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs index f7be702..40b1871 100644 --- a/src/Data/Generic/Rep/Show.purs +++ b/src/Data/Generic/Rep/Show.purs @@ -9,7 +9,8 @@ module Data.Generic.Rep.Show import Prelude (class Show, show, (<>)) import Data.Foldable (intercalate) import Data.Generic.Rep -import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol) +import Data.Symbol (class IsSymbol, reflectSymbol) +import Type.Proxy (Proxy(..)) class GenericShow a where genericShow' :: a -> String @@ -41,7 +42,7 @@ instance genericShowConstructor args -> "(" <> intercalate " " ([ctor] <> args) <> ")" where ctor :: String - ctor = reflectSymbol (SProxy :: SProxy name) + ctor = reflectSymbol (Proxy :: Proxy name) instance genericShowArgsArgument :: Show a => GenericShowArgs (Argument a) where genericShowArgs (Argument a) = [show a] From edfa4a621d4899c8a87aa32665c0ea2abd08cb5e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 19:48:38 -0800 Subject: [PATCH 20/30] Move Enum file to Data.Enum.Generic --- src/Data/{Generic/Rep/Enum.purs => Enum/Generic.purs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Data/{Generic/Rep/Enum.purs => Enum/Generic.purs} (100%) diff --git a/src/Data/Generic/Rep/Enum.purs b/src/Data/Enum/Generic.purs similarity index 100% rename from src/Data/Generic/Rep/Enum.purs rename to src/Data/Enum/Generic.purs From ab11f66c491971d2efb4bf9eb883e8d210022e77 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 19:49:06 -0800 Subject: [PATCH 21/30] Update module name to match file name for Enum --- src/Data/Enum/Generic.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Enum/Generic.purs b/src/Data/Enum/Generic.purs index 594729c..6562408 100644 --- a/src/Data/Enum/Generic.purs +++ b/src/Data/Enum/Generic.purs @@ -1,4 +1,4 @@ -module Data.Generic.Rep.Enum where +module Data.Enum.Generic where import Prelude From 59f837e988e33bed9f9f494f1c2fa589683f2d66 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 19:49:49 -0800 Subject: [PATCH 22/30] Update module path for Bounded Generic --- src/Data/Enum/Generic.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Enum/Generic.purs b/src/Data/Enum/Generic.purs index 6562408..0d59cca 100644 --- a/src/Data/Enum/Generic.purs +++ b/src/Data/Enum/Generic.purs @@ -4,7 +4,7 @@ import Prelude import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum) import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), Sum(..), from, to) -import Data.Generic.Rep.Bounded (class GenericBottom, class GenericTop, genericBottom', genericTop') +import Data.Bounded.Generic (class GenericBottom, class GenericTop, genericBottom', genericTop') import Data.Maybe (Maybe(..)) import Data.Newtype (unwrap) From 8a348a920fc7eac679c6db874c7530f6c141e524 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:00:01 -0800 Subject: [PATCH 23/30] Move test file to Data.Enum folder and rename to Generic.purs --- test/{Main.purs => Test/Data/Enum/Generic.purs} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename test/{Main.purs => Test/Data/Enum/Generic.purs} (99%) diff --git a/test/Main.purs b/test/Test/Data/Enum/Generic.purs similarity index 99% rename from test/Main.purs rename to test/Test/Data/Enum/Generic.purs index 4ae7f7d..97e5c59 100644 --- a/test/Main.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -245,7 +245,7 @@ main = do assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) * A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 5000 {a: 300}) {a: 800}) log "Checking sub" - assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) - A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 50 {a: -20}) {a: -20}) + assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) - A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 50 {a: -20}) {a: -20}) log "Checking ff" assert $ (ff :: B1) == B1 (Tuple (Tuple false {a: false}) {a: false}) @@ -260,4 +260,4 @@ main = do assert $ (B1 (Tuple (Tuple true {a: false}) {a: true}) || B1 (Tuple (Tuple false {a: false}) {a: true})) == B1 (Tuple (Tuple true { a: false }) { a: true }) log "Checking not" - assert $ not B1 (Tuple (Tuple true {a: false}) {a: true}) == B1 (Tuple (Tuple false {a: true}) {a: false}) \ No newline at end of file + assert $ not B1 (Tuple (Tuple true {a: false}) {a: true}) == B1 (Tuple (Tuple false {a: true}) {a: false}) From f5d3c2e40038a3dc840a3e9fd49d760e65c39189 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:01:29 -0800 Subject: [PATCH 24/30] Remove code unrelated to Enum in test file --- test/Test/Data/Enum/Generic.purs | 113 ------------------------------- 1 file changed, 113 deletions(-) diff --git a/test/Test/Data/Enum/Generic.purs b/test/Test/Data/Enum/Generic.purs index 97e5c59..86a9034 100644 --- a/test/Test/Data/Enum/Generic.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -7,31 +7,13 @@ import Data.Generic.Rep as G import Data.Generic.Rep.Bounded as GBounded import Data.Generic.Rep.Enum as GEnum import Data.Generic.Rep.Eq as GEq -import Data.Generic.Rep.HeytingAlgebra as GHeytingAlgebra import Data.Generic.Rep.Ord as GOrd -import Data.Generic.Rep.Ring as GRing -import Data.Generic.Rep.Semiring as GSemiring import Data.Generic.Rep.Show as GShow -import Data.HeytingAlgebra (ff, tt) import Data.Maybe (Maybe(..)) -import Data.Tuple (Tuple(..)) import Effect (Effect) import Effect.Console (log, logShow) import Test.Assert (assert) -data List a = Nil | Cons { head :: a, tail :: List a } - -cons :: forall a. a -> List a -> List a -cons head tail = Cons { head, tail } - -derive instance genericList :: G.Generic (List a) _ - -instance eqList :: Eq a => Eq (List a) where - eq x y = GEq.genericEq x y - -instance showList :: Show a => Show (List a) where - show x = GShow.genericShow x - data SimpleBounded = A | B | C | D derive instance genericSimpleBounded :: G.Generic SimpleBounded _ instance eqSimpleBounded :: Eq SimpleBounded where @@ -108,73 +90,8 @@ instance boundedEnumPair :: (BoundedEnum a, BoundedEnum b) => BoundedEnum (Pair toEnum = GEnum.genericToEnum fromEnum = GEnum.genericFromEnum -data A1 = A1 (Tuple (Tuple Int {a :: Int}) {a :: Int}) -derive instance genericA1 :: G.Generic A1 _ -instance eqA1 :: Eq A1 where - eq a = GEq.genericEq a -instance showA1 :: Show A1 where - show a = GShow.genericShow a -instance semiringA1 :: Semiring A1 where - zero = GSemiring.genericZero - one = GSemiring.genericOne - add x y = GSemiring.genericAdd x y - mul x y = GSemiring.genericMul x y -instance ringA1 :: Ring A1 where - sub x y = GRing.genericSub x y - -data B1 = B1 (Tuple (Tuple Boolean {a :: Boolean}) {a :: Boolean}) -derive instance genericB1 :: G.Generic B1 _ -instance eqB1 :: Eq B1 where - eq a = GEq.genericEq a -instance showB1 :: Show B1 where - show a = GShow.genericShow a -instance heytingAlgebraB1 :: HeytingAlgebra B1 where - ff = GHeytingAlgebra.genericFF - tt = GHeytingAlgebra.genericTT - implies x y = GHeytingAlgebra.genericImplies x y - conj x y = GHeytingAlgebra.genericConj x y - disj x y = GHeytingAlgebra.genericDisj x y - not x = GHeytingAlgebra.genericNot x - -instance booleanAlgebraB1 :: BooleanAlgebra B1 - main :: Effect Unit main = do - logShow (cons 1 (cons 2 Nil)) - - log "Checking equality" - assert $ cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil) - - log "Checking inequality" - assert $ cons 1 (cons 2 Nil) /= cons 1 Nil - - log "Checking comparison EQ" - assert $ (Pair Zero (Some One) `compare` Pair Zero (Some One)) == EQ - - log "Checking comparison GT" - assert $ (Pair (Some One) Zero `compare` Pair (Some Zero) Zero) == GT - - log "Checking comparison LT" - assert $ (Pair Zero One `compare` Pair One One) == LT - - log "Checking simple bottom" - assert $ bottom == A - - log "Checking simple top" - assert $ top == D - - log "Checking composite bottom" - assert $ bottom == (None :: Option SimpleBounded) - - log "Checking composite top" - assert $ top == Some D - - log "Checking product bottom" - assert $ bottom == (Pair Zero A :: Pair Bit SimpleBounded) - - log "Checking product top" - assert $ top == (Pair One D :: Pair Bit SimpleBounded) - log "Checking simple pred bottom" assert $ pred (bottom :: SimpleBounded) == Nothing @@ -231,33 +148,3 @@ main = do log "Checking product toEnum/fromEnum roundtrip" assert $ let allPairs = enumFromTo bottom top :: Array (Pair Bit SimpleBounded) in (toEnum <<< fromEnum <$> allPairs) == (Just <$> allPairs) - - log "Checking zero" - assert $ (zero :: A1) == A1 (Tuple (Tuple 0 {a: 0}) {a: 0}) - - log "Checking one" - assert $ (one :: A1) == A1 (Tuple (Tuple 1 {a: 1}) {a: 1}) - - log "Checking add" - assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) + A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 150 {a: 40}) {a: 60}) - - log "Checking mul" - assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) * A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 5000 {a: 300}) {a: 800}) - - log "Checking sub" - assert $ A1 (Tuple (Tuple 100 {a: 10}) {a: 20}) - A1 (Tuple (Tuple 50 {a: 30}) {a: 40}) == A1 (Tuple (Tuple 50 {a: -20}) {a: -20}) - - log "Checking ff" - assert $ (ff :: B1) == B1 (Tuple (Tuple false {a: false}) {a: false}) - - log "Checking tt" - assert $ (tt :: B1) == B1 (Tuple (Tuple true {a: true}) {a: true}) - - log "Checking conj" - assert $ (B1 (Tuple (Tuple true {a: false}) {a: true}) && B1 (Tuple (Tuple false {a: false}) {a: true})) == B1 (Tuple (Tuple false { a: false }) { a: true }) - - log "Checking disj" - assert $ (B1 (Tuple (Tuple true {a: false}) {a: true}) || B1 (Tuple (Tuple false {a: false}) {a: true})) == B1 (Tuple (Tuple true { a: false }) { a: true }) - - log "Checking not" - assert $ not B1 (Tuple (Tuple true {a: false}) {a: true}) == B1 (Tuple (Tuple false {a: true}) {a: false}) From e01e7b4f2d8d87da5a2f4445691e92cd721df72b Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:02:13 -0800 Subject: [PATCH 25/30] Update Generic X module names to Data.X.Generic --- test/Test/Data/Enum/Generic.purs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/Test/Data/Enum/Generic.purs b/test/Test/Data/Enum/Generic.purs index 86a9034..79e2f9f 100644 --- a/test/Test/Data/Enum/Generic.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -4,11 +4,11 @@ import Prelude import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), cardinality, fromEnum, pred, succ, toEnum, enumFromTo) import Data.Generic.Rep as G -import Data.Generic.Rep.Bounded as GBounded -import Data.Generic.Rep.Enum as GEnum -import Data.Generic.Rep.Eq as GEq -import Data.Generic.Rep.Ord as GOrd -import Data.Generic.Rep.Show as GShow +import Data.Bounded.Generic as GBounded +import Data.Enum.Generic as GEnum +import Data.Eq.Generic as GEq +import Data.Ord.Generic as GOrd +import Data.Show.Generic as GShow import Data.Maybe (Maybe(..)) import Effect (Effect) import Effect.Console (log, logShow) From ac17a31079cdb19670219d77dce9c610672de591 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:02:55 -0800 Subject: [PATCH 26/30] Rename `main` function in test file to testGenericEnum --- test/Test/Data/Enum/Generic.purs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Test/Data/Enum/Generic.purs b/test/Test/Data/Enum/Generic.purs index 79e2f9f..7b52b43 100644 --- a/test/Test/Data/Enum/Generic.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -90,8 +90,8 @@ instance boundedEnumPair :: (BoundedEnum a, BoundedEnum b) => BoundedEnum (Pair toEnum = GEnum.genericToEnum fromEnum = GEnum.genericFromEnum -main :: Effect Unit -main = do +testGenericEnum :: Effect Unit +testGenericEnum = do log "Checking simple pred bottom" assert $ pred (bottom :: SimpleBounded) == Nothing From e6abca2e9f1fdba43747a24525ada4b0a7cd397e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:04:49 -0800 Subject: [PATCH 27/30] Update module name in test file to match file name --- test/Test/Data/Enum/Generic.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Test/Data/Enum/Generic.purs b/test/Test/Data/Enum/Generic.purs index 7b52b43..c0ca63d 100644 --- a/test/Test/Data/Enum/Generic.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -1,4 +1,4 @@ -module Test.Main where +module Test.Data.Enum.Generic where import Prelude From 1c185b7598256b9fdf79057b6270875cc4867ea9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:05:15 -0800 Subject: [PATCH 28/30] Remove all files in repo that are unrelated to Enum Generic --- src/Data/Generic/Rep.purs | 48 ---------------- src/Data/Generic/Rep/Bounded.purs | 56 ------------------- src/Data/Generic/Rep/Eq.purs | 35 ------------ src/Data/Generic/Rep/HeytingAlgebra.purs | 70 ------------------------ src/Data/Generic/Rep/Monoid.purs | 27 --------- src/Data/Generic/Rep/Ord.purs | 39 ------------- src/Data/Generic/Rep/Ring.purs | 24 -------- src/Data/Generic/Rep/Semigroup.purs | 31 ----------- src/Data/Generic/Rep/Semiring.purs | 51 ----------------- src/Data/Generic/Rep/Show.purs | 52 ------------------ 10 files changed, 433 deletions(-) delete mode 100644 src/Data/Generic/Rep.purs delete mode 100644 src/Data/Generic/Rep/Bounded.purs delete mode 100644 src/Data/Generic/Rep/Eq.purs delete mode 100644 src/Data/Generic/Rep/HeytingAlgebra.purs delete mode 100644 src/Data/Generic/Rep/Monoid.purs delete mode 100644 src/Data/Generic/Rep/Ord.purs delete mode 100644 src/Data/Generic/Rep/Ring.purs delete mode 100644 src/Data/Generic/Rep/Semigroup.purs delete mode 100644 src/Data/Generic/Rep/Semiring.purs delete mode 100644 src/Data/Generic/Rep/Show.purs diff --git a/src/Data/Generic/Rep.purs b/src/Data/Generic/Rep.purs deleted file mode 100644 index 92bf845..0000000 --- a/src/Data/Generic/Rep.purs +++ /dev/null @@ -1,48 +0,0 @@ -module Data.Generic.Rep - ( class Generic - , to - , from - , NoConstructors - , NoArguments(..) - , Sum(..) - , Product(..) - , Constructor(..) - , Argument(..) - ) where - -import Data.Maybe (Maybe(..)) - --- | A representation for types with no constructors. -data NoConstructors - --- | A representation for constructors with no arguments. -data NoArguments = NoArguments - --- | A representation for types with multiple constructors. -data Sum a b = Inl a | Inr b - --- | A representation for constructors with multiple fields. -data Product a b = Product a b - --- | A representation for constructors which includes the data constructor name --- | as a type-level string. -newtype Constructor (name :: Symbol) a = Constructor a - --- | A representation for an argument in a data constructor. -newtype Argument a = Argument a - --- | The `Generic` class asserts the existence of a type function from types --- | to their representations using the type constructors defined in this module. -class Generic a rep | a -> rep where - to :: rep -> a - from :: a -> rep - -instance genericMaybe - :: Generic (Maybe a) (Sum (Constructor "Nothing" NoArguments) - (Constructor "Just" (Argument a))) where - to (Inl _) = Nothing - to (Inr (Constructor (Argument a))) = Just a - - from Nothing = Inl (Constructor NoArguments) - from (Just a) = Inr (Constructor (Argument a)) - diff --git a/src/Data/Generic/Rep/Bounded.purs b/src/Data/Generic/Rep/Bounded.purs deleted file mode 100644 index 8b1ec85..0000000 --- a/src/Data/Generic/Rep/Bounded.purs +++ /dev/null @@ -1,56 +0,0 @@ -module Data.Generic.Rep.Bounded - ( class GenericBottom - , genericBottom' - , genericBottom - , class GenericTop - , genericTop' - , genericTop - ) where - -import Data.Generic.Rep - -import Data.Bounded (class Bounded, bottom, top) - -class GenericBottom a where - genericBottom' :: a - -instance genericBottomNoArguments :: GenericBottom NoArguments where - genericBottom' = NoArguments - -instance genericBottomArgument :: Bounded a => GenericBottom (Argument a) where - genericBottom' = Argument bottom - -instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where - genericBottom' = Inl genericBottom' - -instance genericBottomProduct :: (GenericBottom a, GenericBottom b) => GenericBottom (Product a b) where - genericBottom' = Product genericBottom' genericBottom' - -instance genericBottomConstructor :: GenericBottom a => GenericBottom (Constructor name a) where - genericBottom' = Constructor genericBottom' - -class GenericTop a where - genericTop' :: a - -instance genericTopNoArguments :: GenericTop NoArguments where - genericTop' = NoArguments - -instance genericTopArgument :: Bounded a => GenericTop (Argument a) where - genericTop' = Argument top - -instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where - genericTop' = Inr genericTop' - -instance genericTopProduct :: (GenericTop a, GenericTop b) => GenericTop (Product a b) where - genericTop' = Product genericTop' genericTop' - -instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a) where - genericTop' = Constructor genericTop' - --- | A `Generic` implementation of the `bottom` member from the `Bounded` type class. -genericBottom :: forall a rep. Generic a rep => GenericBottom rep => a -genericBottom = to genericBottom' - --- | A `Generic` implementation of the `top` member from the `Bounded` type class. -genericTop :: forall a rep. Generic a rep => GenericTop rep => a -genericTop = to genericTop' diff --git a/src/Data/Generic/Rep/Eq.purs b/src/Data/Generic/Rep/Eq.purs deleted file mode 100644 index fe09ab0..0000000 --- a/src/Data/Generic/Rep/Eq.purs +++ /dev/null @@ -1,35 +0,0 @@ -module Data.Generic.Rep.Eq - ( class GenericEq - , genericEq' - , genericEq - ) where - -import Prelude (class Eq, (==), (&&)) -import Data.Generic.Rep - -class GenericEq a where - genericEq' :: a -> a -> Boolean - -instance genericEqNoConstructors :: GenericEq NoConstructors where - genericEq' _ _ = true - -instance genericEqNoArguments :: GenericEq NoArguments where - genericEq' _ _ = true - -instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where - genericEq' (Inl a1) (Inl a2) = genericEq' a1 a2 - genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2 - genericEq' _ _ = false - -instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where - genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2 - -instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where - genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2 - -instance genericEqArgument :: Eq a => GenericEq (Argument a) where - genericEq' (Argument a1) (Argument a2) = a1 == a2 - --- | A `Generic` implementation of the `eq` member from the `Eq` type class. -genericEq :: forall a rep. Generic a rep => GenericEq rep => a -> a -> Boolean -genericEq x y = genericEq' (from x) (from y) diff --git a/src/Data/Generic/Rep/HeytingAlgebra.purs b/src/Data/Generic/Rep/HeytingAlgebra.purs deleted file mode 100644 index f2223d8..0000000 --- a/src/Data/Generic/Rep/HeytingAlgebra.purs +++ /dev/null @@ -1,70 +0,0 @@ -module Data.Generic.Rep.HeytingAlgebra where - -import Prelude - -import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) -import Data.HeytingAlgebra (ff, implies, tt) - -class GenericHeytingAlgebra a where - genericFF' :: a - genericTT' :: a - genericImplies' :: a -> a -> a - genericConj' :: a -> a -> a - genericDisj' :: a -> a -> a - genericNot' :: a -> a - -instance genericHeytingAlgebraNoArguments :: GenericHeytingAlgebra NoArguments where - genericFF' = NoArguments - genericTT' = NoArguments - genericImplies' _ _ = NoArguments - genericConj' _ _ = NoArguments - genericDisj' _ _ = NoArguments - genericNot' _ = NoArguments - -instance genericHeytingAlgebraArgument :: HeytingAlgebra a => GenericHeytingAlgebra (Argument a) where - genericFF' = Argument ff - genericTT' = Argument tt - genericImplies' (Argument x) (Argument y) = Argument (implies x y) - genericConj' (Argument x) (Argument y) = Argument (conj x y) - genericDisj' (Argument x) (Argument y) = Argument (disj x y) - genericNot' (Argument x) = Argument (not x) - -instance genericHeytingAlgebraProduct :: (GenericHeytingAlgebra a, GenericHeytingAlgebra b) => GenericHeytingAlgebra (Product a b) where - genericFF' = Product genericFF' genericFF' - genericTT' = Product genericTT' genericTT' - genericImplies' (Product a1 b1) (Product a2 b2) = Product (genericImplies' a1 a2) (genericImplies' b1 b2) - genericConj' (Product a1 b1) (Product a2 b2) = Product (genericConj' a1 a2) (genericConj' b1 b2) - genericDisj' (Product a1 b1) (Product a2 b2) = Product (genericDisj' a1 a2) (genericDisj' b1 b2) - genericNot' (Product a b) = Product (genericNot' a) (genericNot' b) - -instance genericHeytingAlgebraConstructor :: GenericHeytingAlgebra a => GenericHeytingAlgebra (Constructor name a) where - genericFF' = Constructor genericFF' - genericTT' = Constructor genericTT' - genericImplies' (Constructor a1) (Constructor a2) = Constructor (genericImplies' a1 a2) - genericConj' (Constructor a1) (Constructor a2) = Constructor (genericConj' a1 a2) - genericDisj' (Constructor a1) (Constructor a2) = Constructor (genericDisj' a1 a2) - genericNot' (Constructor a) = Constructor (genericNot' a) - --- | A `Generic` implementation of the `ff` member from the `HeytingAlgebra` type class. -genericFF :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -genericFF = to genericFF' - --- | A `Generic` implementation of the `tt` member from the `HeytingAlgebra` type class. -genericTT :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -genericTT = to genericTT' - --- | A `Generic` implementation of the `implies` member from the `HeytingAlgebra` type class. -genericImplies :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a -genericImplies x y = to $ from x `genericImplies'` from y - --- | A `Generic` implementation of the `conj` member from the `HeytingAlgebra` type class. -genericConj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a -genericConj x y = to $ from x `genericConj'` from y - --- | A `Generic` implementation of the `disj` member from the `HeytingAlgebra` type class. -genericDisj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a -genericDisj x y = to $ from x `genericDisj'` from y - --- | A `Generic` implementation of the `not` member from the `HeytingAlgebra` type class. -genericNot :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -genericNot x = to $ genericNot' (from x) \ No newline at end of file diff --git a/src/Data/Generic/Rep/Monoid.purs b/src/Data/Generic/Rep/Monoid.purs deleted file mode 100644 index 999b2f5..0000000 --- a/src/Data/Generic/Rep/Monoid.purs +++ /dev/null @@ -1,27 +0,0 @@ -module Data.Generic.Rep.Monoid - ( class GenericMonoid - , genericMempty' - , genericMempty - ) where - -import Data.Monoid (class Monoid, mempty) -import Data.Generic.Rep - -class GenericMonoid a where - genericMempty' :: a - -instance genericMonoidNoArguments :: GenericMonoid NoArguments where - genericMempty' = NoArguments - -instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where - genericMempty' = Product genericMempty' genericMempty' - -instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where - genericMempty' = Constructor genericMempty' - -instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where - genericMempty' = Argument mempty - --- | A `Generic` implementation of the `mempty` member from the `Monoid` type class. -genericMempty :: forall a rep. Generic a rep => GenericMonoid rep => a -genericMempty = to genericMempty' diff --git a/src/Data/Generic/Rep/Ord.purs b/src/Data/Generic/Rep/Ord.purs deleted file mode 100644 index ad7c45c..0000000 --- a/src/Data/Generic/Rep/Ord.purs +++ /dev/null @@ -1,39 +0,0 @@ -module Data.Generic.Rep.Ord - ( class GenericOrd - , genericCompare' - , genericCompare - ) where - -import Prelude (class Ord, compare, Ordering(..)) -import Data.Generic.Rep - -class GenericOrd a where - genericCompare' :: a -> a -> Ordering - -instance genericOrdNoConstructors :: GenericOrd NoConstructors where - genericCompare' _ _ = EQ - -instance genericOrdNoArguments :: GenericOrd NoArguments where - genericCompare' _ _ = EQ - -instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) where - genericCompare' (Inl a1) (Inl a2) = genericCompare' a1 a2 - genericCompare' (Inr b1) (Inr b2) = genericCompare' b1 b2 - genericCompare' (Inl b1) (Inr b2) = LT - genericCompare' (Inr b1) (Inl b2) = GT - -instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where - genericCompare' (Product a1 b1) (Product a2 b2) = - case genericCompare' a1 a2 of - EQ -> genericCompare' b1 b2 - other -> other - -instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where - genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2 - -instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where - genericCompare' (Argument a1) (Argument a2) = compare a1 a2 - --- | A `Generic` implementation of the `compare` member from the `Ord` type class. -genericCompare :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering -genericCompare x y = genericCompare' (from x) (from y) diff --git a/src/Data/Generic/Rep/Ring.purs b/src/Data/Generic/Rep/Ring.purs deleted file mode 100644 index f5c73f3..0000000 --- a/src/Data/Generic/Rep/Ring.purs +++ /dev/null @@ -1,24 +0,0 @@ -module Data.Generic.Rep.Ring where - -import Prelude - -import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) - -class GenericRing a where - genericSub' :: a -> a -> a - -instance genericRingNoArguments :: GenericRing NoArguments where - genericSub' _ _ = NoArguments - -instance genericRingArgument :: Ring a => GenericRing (Argument a) where - genericSub' (Argument x) (Argument y) = Argument (sub x y) - -instance genericRingProduct :: (GenericRing a, GenericRing b) => GenericRing (Product a b) where - genericSub' (Product a1 b1) (Product a2 b2) = Product (genericSub' a1 a2) (genericSub' b1 b2) - -instance genericRingConstructor :: GenericRing a => GenericRing (Constructor name a) where - genericSub' (Constructor a1) (Constructor a2) = Constructor (genericSub' a1 a2) - --- | A `Generic` implementation of the `sub` member from the `Ring` type class. -genericSub :: forall a rep. Generic a rep => GenericRing rep => a -> a -> a -genericSub x y = to $ from x `genericSub'` from y \ No newline at end of file diff --git a/src/Data/Generic/Rep/Semigroup.purs b/src/Data/Generic/Rep/Semigroup.purs deleted file mode 100644 index 1ab5606..0000000 --- a/src/Data/Generic/Rep/Semigroup.purs +++ /dev/null @@ -1,31 +0,0 @@ -module Data.Generic.Rep.Semigroup - ( class GenericSemigroup - , genericAppend' - , genericAppend - ) where - -import Prelude (class Semigroup, append) -import Data.Generic.Rep - -class GenericSemigroup a where - genericAppend' :: a -> a -> a - -instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where - genericAppend' a _ = a - -instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where - genericAppend' a _ = a - -instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where - genericAppend' (Product a1 b1) (Product a2 b2) = - Product (genericAppend' a1 a2) (genericAppend' b1 b2) - -instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where - genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2) - -instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where - genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2) - --- | A `Generic` implementation of the `append` member from the `Semigroup` type class. -genericAppend :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a -genericAppend x y = to (genericAppend' (from x) (from y)) diff --git a/src/Data/Generic/Rep/Semiring.purs b/src/Data/Generic/Rep/Semiring.purs deleted file mode 100644 index b6b2412..0000000 --- a/src/Data/Generic/Rep/Semiring.purs +++ /dev/null @@ -1,51 +0,0 @@ -module Data.Generic.Rep.Semiring where - -import Prelude - -import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to) - -class GenericSemiring a where - genericAdd' :: a -> a -> a - genericZero' :: a - genericMul' :: a -> a -> a - genericOne' :: a - -instance genericSemiringNoArguments :: GenericSemiring NoArguments where - genericAdd' _ _ = NoArguments - genericZero' = NoArguments - genericMul' _ _ = NoArguments - genericOne' = NoArguments - -instance genericSemiringArgument :: Semiring a => GenericSemiring (Argument a) where - genericAdd' (Argument x) (Argument y) = Argument (add x y) - genericZero' = Argument zero - genericMul' (Argument x) (Argument y) = Argument (mul x y) - genericOne' = Argument one - -instance genericSemiringProduct :: (GenericSemiring a, GenericSemiring b) => GenericSemiring (Product a b) where - genericAdd' (Product a1 b1) (Product a2 b2) = Product (genericAdd' a1 a2) (genericAdd' b1 b2) - genericZero' = Product genericZero' genericZero' - genericMul' (Product a1 b1) (Product a2 b2) = Product (genericMul' a1 a2) (genericMul' b1 b2) - genericOne' = Product genericOne' genericOne' - -instance genericSemiringConstructor :: GenericSemiring a => GenericSemiring (Constructor name a) where - genericAdd' (Constructor a1) (Constructor a2) = Constructor (genericAdd' a1 a2) - genericZero' = Constructor genericZero' - genericMul' (Constructor a1) (Constructor a2) = Constructor (genericMul' a1 a2) - genericOne' = Constructor genericOne' - --- | A `Generic` implementation of the `zero` member from the `Semiring` type class. -genericZero :: forall a rep. Generic a rep => GenericSemiring rep => a -genericZero = to genericZero' - --- | A `Generic` implementation of the `one` member from the `Semiring` type class. -genericOne :: forall a rep. Generic a rep => GenericSemiring rep => a -genericOne = to genericOne' - --- | A `Generic` implementation of the `add` member from the `Semiring` type class. -genericAdd :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a -genericAdd x y = to $ from x `genericAdd'` from y - --- | A `Generic` implementation of the `mul` member from the `Semiring` type class. -genericMul :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a -genericMul x y = to $ from x `genericMul'` from y \ No newline at end of file diff --git a/src/Data/Generic/Rep/Show.purs b/src/Data/Generic/Rep/Show.purs deleted file mode 100644 index 40b1871..0000000 --- a/src/Data/Generic/Rep/Show.purs +++ /dev/null @@ -1,52 +0,0 @@ -module Data.Generic.Rep.Show - ( class GenericShow - , genericShow' - , genericShow - , class GenericShowArgs - , genericShowArgs - ) where - -import Prelude (class Show, show, (<>)) -import Data.Foldable (intercalate) -import Data.Generic.Rep -import Data.Symbol (class IsSymbol, reflectSymbol) -import Type.Proxy (Proxy(..)) - -class GenericShow a where - genericShow' :: a -> String - -class GenericShowArgs a where - genericShowArgs :: a -> Array String - -instance genericShowNoConstructors :: GenericShow NoConstructors where - genericShow' a = genericShow' a - -instance genericShowArgsNoArguments :: GenericShowArgs NoArguments where - genericShowArgs _ = [] - -instance genericShowSum :: (GenericShow a, GenericShow b) => GenericShow (Sum a b) where - genericShow' (Inl a) = genericShow' a - genericShow' (Inr b) = genericShow' b - -instance genericShowArgsProduct - :: (GenericShowArgs a, GenericShowArgs b) - => GenericShowArgs (Product a b) where - genericShowArgs (Product a b) = genericShowArgs a <> genericShowArgs b - -instance genericShowConstructor - :: (GenericShowArgs a, IsSymbol name) - => GenericShow (Constructor name a) where - genericShow' (Constructor a) = - case genericShowArgs a of - [] -> ctor - args -> "(" <> intercalate " " ([ctor] <> args) <> ")" - where - ctor :: String - ctor = reflectSymbol (Proxy :: Proxy name) - -instance genericShowArgsArgument :: Show a => GenericShowArgs (Argument a) where - genericShowArgs (Argument a) = [show a] - --- | A `Generic` implementation of the `show` member from the `Show` type class. -genericShow :: forall a rep. Generic a rep => GenericShow rep => a -> String -genericShow x = genericShow' (from x) From 8bbb2aabc8470114e4c680dff30bdc3379b885b3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:13:37 -0800 Subject: [PATCH 29/30] Include Enum's Generic tests in repo's tests --- test/Main.purs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/Main.purs b/test/Main.purs index b8d6c38..c4a74e6 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -4,6 +4,9 @@ import Prelude import Effect (Effect) import Test.Data.Enum (testEnum) +import Test.Data.Enum.Generic (testGenericEnum) main :: Effect Unit -main = testEnum +main = do + testEnum + testGenericEnum From 4469b2e9143f21db10812eeb8acf0c25bc94da9e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 24 Dec 2020 20:14:40 -0800 Subject: [PATCH 30/30] Remove unused logShow --- test/Test/Data/Enum/Generic.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Test/Data/Enum/Generic.purs b/test/Test/Data/Enum/Generic.purs index c0ca63d..7472119 100644 --- a/test/Test/Data/Enum/Generic.purs +++ b/test/Test/Data/Enum/Generic.purs @@ -11,7 +11,7 @@ import Data.Ord.Generic as GOrd import Data.Show.Generic as GShow import Data.Maybe (Maybe(..)) import Effect (Effect) -import Effect.Console (log, logShow) +import Effect.Console (log) import Test.Assert (assert) data SimpleBounded = A | B | C | D