Skip to content

Commit b8e3453

Browse files
JordanMartinezpaf31matthewleongarybLiamGoodacre
authored
Port generics-rep to prelude (#235)
* first commit * Fix instances for record fields * Break modules up * Deriving Show (#5) * Initial work on deriving Show * Add test for Show * Remove import * Travis etc. * 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 * Update for PureScript 0.11 * Add Generic instance for Maybe (#9) * Add missing Bounded instances for Argument * Add GenericEnum and GenericBoundedEnum * Add enum tests, convert existing "tests" into assertions * Product instances in Bounded and Enum * 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 * Remove Rec and Field & update package & bower symbols * Bump deps for compiler/0.12 * Remove symbols and fix operator fixity issue * Update dependencies, license * Added HeytingAlgebra, Semiring, Ring * Fix type annotation precedence in tests * Replace monomorphic proxies by Type.Proxy.Proxy (#44) * Remove Generic Maybe instance * Remove Generic Enum from src and test * Move all files to their correct folders and rename files to Generic.purs * Update module names to match their file names * Move test file for Data.Generic.Rep into proper folder and rename * Update generic-rep test file module to match file path * Rename generic-rep test name to testGenericRep * Replace generic Show's Foldable.intercalate usage with FFI * Replace Tuple with Pair in Data.Generic.Rep tests * Remove Maybe import from Data.Generic.Rep test file * Remove Maybe import from Data.Generic.Rep * Extract AlmostEff and assert to Test.Utils.purs file * Update Data.Generic.Rep tests to use AlmostEff; include it in main tests * Import implies in Data.Generic.Rep tests Co-authored-by: Phil Freeman <[email protected]> Co-authored-by: Matthew Leon <[email protected]> Co-authored-by: Gary Burgess <[email protected]> Co-authored-by: Liam Goodacre <[email protected]> Co-authored-by: Jorge Acereda <[email protected]> Co-authored-by: Kristoffer Josefsson <[email protected]> Co-authored-by: Denis Stoyanov <[email protected]> Co-authored-by: Harry Garrood <[email protected]> Co-authored-by: Cyril <[email protected]>
1 parent 0c1d607 commit b8e3453

File tree

16 files changed

+643
-13
lines changed

16 files changed

+643
-13
lines changed

src/Data/Bounded/Generic.purs

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module Data.Bounded.Generic
2+
( class GenericBottom
3+
, genericBottom'
4+
, genericBottom
5+
, class GenericTop
6+
, genericTop'
7+
, genericTop
8+
) where
9+
10+
import Data.Generic.Rep
11+
12+
import Data.Bounded (class Bounded, bottom, top)
13+
14+
class GenericBottom a where
15+
genericBottom' :: a
16+
17+
instance genericBottomNoArguments :: GenericBottom NoArguments where
18+
genericBottom' = NoArguments
19+
20+
instance genericBottomArgument :: Bounded a => GenericBottom (Argument a) where
21+
genericBottom' = Argument bottom
22+
23+
instance genericBottomSum :: GenericBottom a => GenericBottom (Sum a b) where
24+
genericBottom' = Inl genericBottom'
25+
26+
instance genericBottomProduct :: (GenericBottom a, GenericBottom b) => GenericBottom (Product a b) where
27+
genericBottom' = Product genericBottom' genericBottom'
28+
29+
instance genericBottomConstructor :: GenericBottom a => GenericBottom (Constructor name a) where
30+
genericBottom' = Constructor genericBottom'
31+
32+
class GenericTop a where
33+
genericTop' :: a
34+
35+
instance genericTopNoArguments :: GenericTop NoArguments where
36+
genericTop' = NoArguments
37+
38+
instance genericTopArgument :: Bounded a => GenericTop (Argument a) where
39+
genericTop' = Argument top
40+
41+
instance genericTopSum :: GenericTop b => GenericTop (Sum a b) where
42+
genericTop' = Inr genericTop'
43+
44+
instance genericTopProduct :: (GenericTop a, GenericTop b) => GenericTop (Product a b) where
45+
genericTop' = Product genericTop' genericTop'
46+
47+
instance genericTopConstructor :: GenericTop a => GenericTop (Constructor name a) where
48+
genericTop' = Constructor genericTop'
49+
50+
-- | A `Generic` implementation of the `bottom` member from the `Bounded` type class.
51+
genericBottom :: forall a rep. Generic a rep => GenericBottom rep => a
52+
genericBottom = to genericBottom'
53+
54+
-- | A `Generic` implementation of the `top` member from the `Bounded` type class.
55+
genericTop :: forall a rep. Generic a rep => GenericTop rep => a
56+
genericTop = to genericTop'

src/Data/Eq/Generic.purs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module Data.Eq.Generic
2+
( class GenericEq
3+
, genericEq'
4+
, genericEq
5+
) where
6+
7+
import Prelude (class Eq, (==), (&&))
8+
import Data.Generic.Rep
9+
10+
class GenericEq a where
11+
genericEq' :: a -> a -> Boolean
12+
13+
instance genericEqNoConstructors :: GenericEq NoConstructors where
14+
genericEq' _ _ = true
15+
16+
instance genericEqNoArguments :: GenericEq NoArguments where
17+
genericEq' _ _ = true
18+
19+
instance genericEqSum :: (GenericEq a, GenericEq b) => GenericEq (Sum a b) where
20+
genericEq' (Inl a1) (Inl a2) = genericEq' a1 a2
21+
genericEq' (Inr b1) (Inr b2) = genericEq' b1 b2
22+
genericEq' _ _ = false
23+
24+
instance genericEqProduct :: (GenericEq a, GenericEq b) => GenericEq (Product a b) where
25+
genericEq' (Product a1 b1) (Product a2 b2) = genericEq' a1 a2 && genericEq' b1 b2
26+
27+
instance genericEqConstructor :: GenericEq a => GenericEq (Constructor name a) where
28+
genericEq' (Constructor a1) (Constructor a2) = genericEq' a1 a2
29+
30+
instance genericEqArgument :: Eq a => GenericEq (Argument a) where
31+
genericEq' (Argument a1) (Argument a2) = a1 == a2
32+
33+
-- | A `Generic` implementation of the `eq` member from the `Eq` type class.
34+
genericEq :: forall a rep. Generic a rep => GenericEq rep => a -> a -> Boolean
35+
genericEq x y = genericEq' (from x) (from y)

src/Data/Generic/Rep.purs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Data.Generic.Rep
2+
( class Generic
3+
, to
4+
, from
5+
, NoConstructors
6+
, NoArguments(..)
7+
, Sum(..)
8+
, Product(..)
9+
, Constructor(..)
10+
, Argument(..)
11+
) where
12+
13+
-- | A representation for types with no constructors.
14+
data NoConstructors
15+
16+
-- | A representation for constructors with no arguments.
17+
data NoArguments = NoArguments
18+
19+
-- | A representation for types with multiple constructors.
20+
data Sum a b = Inl a | Inr b
21+
22+
-- | A representation for constructors with multiple fields.
23+
data Product a b = Product a b
24+
25+
-- | A representation for constructors which includes the data constructor name
26+
-- | as a type-level string.
27+
newtype Constructor (name :: Symbol) a = Constructor a
28+
29+
-- | A representation for an argument in a data constructor.
30+
newtype Argument a = Argument a
31+
32+
-- | The `Generic` class asserts the existence of a type function from types
33+
-- | to their representations using the type constructors defined in this module.
34+
class Generic a rep | a -> rep where
35+
to :: rep -> a
36+
from :: a -> rep

src/Data/HeytingAlgebra/Generic.purs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
module Data.HeytingAlgebra.Generic where
2+
3+
import Prelude
4+
5+
import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to)
6+
import Data.HeytingAlgebra (ff, implies, tt)
7+
8+
class GenericHeytingAlgebra a where
9+
genericFF' :: a
10+
genericTT' :: a
11+
genericImplies' :: a -> a -> a
12+
genericConj' :: a -> a -> a
13+
genericDisj' :: a -> a -> a
14+
genericNot' :: a -> a
15+
16+
instance genericHeytingAlgebraNoArguments :: GenericHeytingAlgebra NoArguments where
17+
genericFF' = NoArguments
18+
genericTT' = NoArguments
19+
genericImplies' _ _ = NoArguments
20+
genericConj' _ _ = NoArguments
21+
genericDisj' _ _ = NoArguments
22+
genericNot' _ = NoArguments
23+
24+
instance genericHeytingAlgebraArgument :: HeytingAlgebra a => GenericHeytingAlgebra (Argument a) where
25+
genericFF' = Argument ff
26+
genericTT' = Argument tt
27+
genericImplies' (Argument x) (Argument y) = Argument (implies x y)
28+
genericConj' (Argument x) (Argument y) = Argument (conj x y)
29+
genericDisj' (Argument x) (Argument y) = Argument (disj x y)
30+
genericNot' (Argument x) = Argument (not x)
31+
32+
instance genericHeytingAlgebraProduct :: (GenericHeytingAlgebra a, GenericHeytingAlgebra b) => GenericHeytingAlgebra (Product a b) where
33+
genericFF' = Product genericFF' genericFF'
34+
genericTT' = Product genericTT' genericTT'
35+
genericImplies' (Product a1 b1) (Product a2 b2) = Product (genericImplies' a1 a2) (genericImplies' b1 b2)
36+
genericConj' (Product a1 b1) (Product a2 b2) = Product (genericConj' a1 a2) (genericConj' b1 b2)
37+
genericDisj' (Product a1 b1) (Product a2 b2) = Product (genericDisj' a1 a2) (genericDisj' b1 b2)
38+
genericNot' (Product a b) = Product (genericNot' a) (genericNot' b)
39+
40+
instance genericHeytingAlgebraConstructor :: GenericHeytingAlgebra a => GenericHeytingAlgebra (Constructor name a) where
41+
genericFF' = Constructor genericFF'
42+
genericTT' = Constructor genericTT'
43+
genericImplies' (Constructor a1) (Constructor a2) = Constructor (genericImplies' a1 a2)
44+
genericConj' (Constructor a1) (Constructor a2) = Constructor (genericConj' a1 a2)
45+
genericDisj' (Constructor a1) (Constructor a2) = Constructor (genericDisj' a1 a2)
46+
genericNot' (Constructor a) = Constructor (genericNot' a)
47+
48+
-- | A `Generic` implementation of the `ff` member from the `HeytingAlgebra` type class.
49+
genericFF :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a
50+
genericFF = to genericFF'
51+
52+
-- | A `Generic` implementation of the `tt` member from the `HeytingAlgebra` type class.
53+
genericTT :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a
54+
genericTT = to genericTT'
55+
56+
-- | A `Generic` implementation of the `implies` member from the `HeytingAlgebra` type class.
57+
genericImplies :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a
58+
genericImplies x y = to $ from x `genericImplies'` from y
59+
60+
-- | A `Generic` implementation of the `conj` member from the `HeytingAlgebra` type class.
61+
genericConj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a
62+
genericConj x y = to $ from x `genericConj'` from y
63+
64+
-- | A `Generic` implementation of the `disj` member from the `HeytingAlgebra` type class.
65+
genericDisj :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a -> a
66+
genericDisj x y = to $ from x `genericDisj'` from y
67+
68+
-- | A `Generic` implementation of the `not` member from the `HeytingAlgebra` type class.
69+
genericNot :: forall a rep. Generic a rep => GenericHeytingAlgebra rep => a -> a
70+
genericNot x = to $ genericNot' (from x)

src/Data/Monoid/Generic.purs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Data.Monoid.Generic
2+
( class GenericMonoid
3+
, genericMempty'
4+
, genericMempty
5+
) where
6+
7+
import Data.Monoid (class Monoid, mempty)
8+
import Data.Generic.Rep
9+
10+
class GenericMonoid a where
11+
genericMempty' :: a
12+
13+
instance genericMonoidNoArguments :: GenericMonoid NoArguments where
14+
genericMempty' = NoArguments
15+
16+
instance genericMonoidProduct :: (GenericMonoid a, GenericMonoid b) => GenericMonoid (Product a b) where
17+
genericMempty' = Product genericMempty' genericMempty'
18+
19+
instance genericMonoidConstructor :: GenericMonoid a => GenericMonoid (Constructor name a) where
20+
genericMempty' = Constructor genericMempty'
21+
22+
instance genericMonoidArgument :: Monoid a => GenericMonoid (Argument a) where
23+
genericMempty' = Argument mempty
24+
25+
-- | A `Generic` implementation of the `mempty` member from the `Monoid` type class.
26+
genericMempty :: forall a rep. Generic a rep => GenericMonoid rep => a
27+
genericMempty = to genericMempty'

src/Data/Ord/Generic.purs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module Data.Ord.Generic
2+
( class GenericOrd
3+
, genericCompare'
4+
, genericCompare
5+
) where
6+
7+
import Prelude (class Ord, compare, Ordering(..))
8+
import Data.Generic.Rep
9+
10+
class GenericOrd a where
11+
genericCompare' :: a -> a -> Ordering
12+
13+
instance genericOrdNoConstructors :: GenericOrd NoConstructors where
14+
genericCompare' _ _ = EQ
15+
16+
instance genericOrdNoArguments :: GenericOrd NoArguments where
17+
genericCompare' _ _ = EQ
18+
19+
instance genericOrdSum :: (GenericOrd a, GenericOrd b) => GenericOrd (Sum a b) where
20+
genericCompare' (Inl a1) (Inl a2) = genericCompare' a1 a2
21+
genericCompare' (Inr b1) (Inr b2) = genericCompare' b1 b2
22+
genericCompare' (Inl b1) (Inr b2) = LT
23+
genericCompare' (Inr b1) (Inl b2) = GT
24+
25+
instance genericOrdProduct :: (GenericOrd a, GenericOrd b) => GenericOrd (Product a b) where
26+
genericCompare' (Product a1 b1) (Product a2 b2) =
27+
case genericCompare' a1 a2 of
28+
EQ -> genericCompare' b1 b2
29+
other -> other
30+
31+
instance genericOrdConstructor :: GenericOrd a => GenericOrd (Constructor name a) where
32+
genericCompare' (Constructor a1) (Constructor a2) = genericCompare' a1 a2
33+
34+
instance genericOrdArgument :: Ord a => GenericOrd (Argument a) where
35+
genericCompare' (Argument a1) (Argument a2) = compare a1 a2
36+
37+
-- | A `Generic` implementation of the `compare` member from the `Ord` type class.
38+
genericCompare :: forall a rep. Generic a rep => GenericOrd rep => a -> a -> Ordering
39+
genericCompare x y = genericCompare' (from x) (from y)

src/Data/Ring/Generic.purs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Data.Ring.Generic where
2+
3+
import Prelude
4+
5+
import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to)
6+
7+
class GenericRing a where
8+
genericSub' :: a -> a -> a
9+
10+
instance genericRingNoArguments :: GenericRing NoArguments where
11+
genericSub' _ _ = NoArguments
12+
13+
instance genericRingArgument :: Ring a => GenericRing (Argument a) where
14+
genericSub' (Argument x) (Argument y) = Argument (sub x y)
15+
16+
instance genericRingProduct :: (GenericRing a, GenericRing b) => GenericRing (Product a b) where
17+
genericSub' (Product a1 b1) (Product a2 b2) = Product (genericSub' a1 a2) (genericSub' b1 b2)
18+
19+
instance genericRingConstructor :: GenericRing a => GenericRing (Constructor name a) where
20+
genericSub' (Constructor a1) (Constructor a2) = Constructor (genericSub' a1 a2)
21+
22+
-- | A `Generic` implementation of the `sub` member from the `Ring` type class.
23+
genericSub :: forall a rep. Generic a rep => GenericRing rep => a -> a -> a
24+
genericSub x y = to $ from x `genericSub'` from y

src/Data/Semigroup/Generic.purs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Data.Semigroup.Generic
2+
( class GenericSemigroup
3+
, genericAppend'
4+
, genericAppend
5+
) where
6+
7+
import Prelude (class Semigroup, append)
8+
import Data.Generic.Rep
9+
10+
class GenericSemigroup a where
11+
genericAppend' :: a -> a -> a
12+
13+
instance genericSemigroupNoConstructors :: GenericSemigroup NoConstructors where
14+
genericAppend' a _ = a
15+
16+
instance genericSemigroupNoArguments :: GenericSemigroup NoArguments where
17+
genericAppend' a _ = a
18+
19+
instance genericSemigroupProduct :: (GenericSemigroup a, GenericSemigroup b) => GenericSemigroup (Product a b) where
20+
genericAppend' (Product a1 b1) (Product a2 b2) =
21+
Product (genericAppend' a1 a2) (genericAppend' b1 b2)
22+
23+
instance genericSemigroupConstructor :: GenericSemigroup a => GenericSemigroup (Constructor name a) where
24+
genericAppend' (Constructor a1) (Constructor a2) = Constructor (genericAppend' a1 a2)
25+
26+
instance genericSemigroupArgument :: Semigroup a => GenericSemigroup (Argument a) where
27+
genericAppend' (Argument a1) (Argument a2) = Argument (append a1 a2)
28+
29+
-- | A `Generic` implementation of the `append` member from the `Semigroup` type class.
30+
genericAppend :: forall a rep. Generic a rep => GenericSemigroup rep => a -> a -> a
31+
genericAppend x y = to (genericAppend' (from x) (from y))

src/Data/Semiring/Generic.purs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module Data.Semiring.Generic where
2+
3+
import Prelude
4+
5+
import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), Product(..), from, to)
6+
7+
class GenericSemiring a where
8+
genericAdd' :: a -> a -> a
9+
genericZero' :: a
10+
genericMul' :: a -> a -> a
11+
genericOne' :: a
12+
13+
instance genericSemiringNoArguments :: GenericSemiring NoArguments where
14+
genericAdd' _ _ = NoArguments
15+
genericZero' = NoArguments
16+
genericMul' _ _ = NoArguments
17+
genericOne' = NoArguments
18+
19+
instance genericSemiringArgument :: Semiring a => GenericSemiring (Argument a) where
20+
genericAdd' (Argument x) (Argument y) = Argument (add x y)
21+
genericZero' = Argument zero
22+
genericMul' (Argument x) (Argument y) = Argument (mul x y)
23+
genericOne' = Argument one
24+
25+
instance genericSemiringProduct :: (GenericSemiring a, GenericSemiring b) => GenericSemiring (Product a b) where
26+
genericAdd' (Product a1 b1) (Product a2 b2) = Product (genericAdd' a1 a2) (genericAdd' b1 b2)
27+
genericZero' = Product genericZero' genericZero'
28+
genericMul' (Product a1 b1) (Product a2 b2) = Product (genericMul' a1 a2) (genericMul' b1 b2)
29+
genericOne' = Product genericOne' genericOne'
30+
31+
instance genericSemiringConstructor :: GenericSemiring a => GenericSemiring (Constructor name a) where
32+
genericAdd' (Constructor a1) (Constructor a2) = Constructor (genericAdd' a1 a2)
33+
genericZero' = Constructor genericZero'
34+
genericMul' (Constructor a1) (Constructor a2) = Constructor (genericMul' a1 a2)
35+
genericOne' = Constructor genericOne'
36+
37+
-- | A `Generic` implementation of the `zero` member from the `Semiring` type class.
38+
genericZero :: forall a rep. Generic a rep => GenericSemiring rep => a
39+
genericZero = to genericZero'
40+
41+
-- | A `Generic` implementation of the `one` member from the `Semiring` type class.
42+
genericOne :: forall a rep. Generic a rep => GenericSemiring rep => a
43+
genericOne = to genericOne'
44+
45+
-- | A `Generic` implementation of the `add` member from the `Semiring` type class.
46+
genericAdd :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a
47+
genericAdd x y = to $ from x `genericAdd'` from y
48+
49+
-- | A `Generic` implementation of the `mul` member from the `Semiring` type class.
50+
genericMul :: forall a rep. Generic a rep => GenericSemiring rep => a -> a -> a
51+
genericMul x y = to $ from x `genericMul'` from y

src/Data/Show/Generic.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict";
2+
3+
exports.intercalate = function (separator) {
4+
return function (xs) {
5+
var len = xs.length;
6+
if (len === 0) return "";
7+
8+
var res = xs[0];
9+
for (var i = 1; i < len; i++) {
10+
res = res + separator + xs[i];
11+
}
12+
return res;
13+
};
14+
};

0 commit comments

Comments
 (0)