Skip to content

Commit c102507

Browse files
Jimmy HartzellEricson2314
Jimmy Hartzell
authored andcommitted
Add instances for :+: and :*:
1 parent 6efbd3b commit c102507

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Unreleased
2+
3+
- Add instances for `:+:` and `:*:`
4+
15
# 1.0.3
26

37
- Make `GNFData` PolyKinded.

src/Data/GADT/Internal.hs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import Data.Maybe (isJust, isNothing)
2727
import Data.Monoid (Monoid (..))
2828
import Data.Semigroup (Semigroup (..))
2929
import Data.Type.Equality ((:~:) (..))
30+
#if MIN_VERSION_base(4,6,0)
31+
import GHC.Generics ((:+:) (..), (:*:) (..))
32+
#endif
3033

3134
#if __GLASGOW_HASKELL__ >=708
3235
import Data.Typeable (Typeable)
@@ -86,6 +89,28 @@ instance (GShow a, GShow b) => GShow (Product a b) where
8689
. showChar ' '
8790
. gshowsPrec 11 y
8891

92+
#if MIN_VERSION_base(4,6,0)
93+
--
94+
-- | >>> gshow (L1 Refl :: ((:~:) Int :+: (:~:) Bool) Int)
95+
-- "L1 Refl"
96+
--
97+
-- @since 1.0.4
98+
instance (GShow a, GShow b) => GShow (a :+: b) where
99+
gshowsPrec d = \s -> case s of
100+
L1 x -> showParen (d > 10) (showString "L1 " . gshowsPrec 11 x)
101+
R1 x -> showParen (d > 10) (showString "R1 " . gshowsPrec 11 x)
102+
103+
-- | >>> gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)
104+
-- "Refl :*: Refl"
105+
--
106+
-- @since 1.0.4
107+
instance (GShow a, GShow b) => GShow (a :*: b) where
108+
gshowsPrec d (x :*: y) = showParen (d > 6)
109+
$ gshowsPrec 6 x
110+
. showString " :*: "
111+
. gshowsPrec 6 y
112+
#endif
113+
89114
-- |@GReadS t@ is equivalent to @ReadS (forall b. (forall a. t a -> b) -> b)@, which is
90115
-- in turn equivalent to @ReadS (Exists t)@ (with @data Exists t where Exists :: t a -> Exists t@)
91116
#if __GLASGOW_HASKELL__ >= 810
@@ -121,6 +146,11 @@ gread s g = withSome (hd [f | (f, "") <- greads s]) g where
121146
-- >>> greadMaybe "InL Refl" mkSome :: Maybe (Some (Sum ((:~:) Int) ((:~:) Bool)))
122147
-- Just (mkSome (InL Refl))
123148
--
149+
#if MIN_VERSION_base(4,6,0)
150+
-- >>> greadMaybe "L1 Refl" mkSome :: Maybe (Some ((:~:) Int :+: (:~:) Bool))
151+
-- Just (mkSome (L1 Refl))
152+
--
153+
#endif
124154
-- >>> greadMaybe "garbage" mkSome :: Maybe (Some ((:~:) Int))
125155
-- Nothing
126156
--
@@ -147,6 +177,21 @@ instance (GRead a, GRead b) => GRead (Sum a b) where
147177
| ("InR", s2) <- lex s1
148178
, (r, t) <- greadsPrec 11 s2 ]) s
149179

180+
#if MIN_VERSION_base(4,6,0)
181+
-- | @since 1.0.4
182+
instance (GRead a, GRead b) => GRead (a :+: b) where
183+
greadsPrec d s =
184+
readParen (d > 10)
185+
(\s1 -> [ (S $ \k -> withSome r (k . L1), t)
186+
| ("L1", s2) <- lex s1
187+
, (r, t) <- greadsPrec 11 s2 ]) s
188+
++
189+
readParen (d > 10)
190+
(\s1 -> [ (S $ \k -> withSome r (k . R1), t)
191+
| ("R1", s2) <- lex s1
192+
, (r, t) <- greadsPrec 11 s2 ]) s
193+
#endif
194+
150195
-------------------------------------------------------------------------------
151196
-- GEq
152197
-------------------------------------------------------------------------------
@@ -199,6 +244,21 @@ instance (GEq a, GEq b) => GEq (Product a b) where
199244
Refl <- geq y y'
200245
return Refl
201246

247+
#if MIN_VERSION_base(4,6,0)
248+
-- | @since 1.0.4
249+
instance (GEq f, GEq g) => GEq (f :+: g) where
250+
geq (L1 x) (L1 y) = geq x y
251+
geq (R1 x) (R1 y) = geq x y
252+
geq _ _ = Nothing
253+
254+
-- | @since 1.0.4
255+
instance (GEq a, GEq b) => GEq (a :*: b) where
256+
geq (x :*: y) (x' :*: y') = do
257+
Refl <- geq x x'
258+
Refl <- geq y y'
259+
return Refl
260+
#endif
261+
202262
#if MIN_VERSION_base(4,10,0)
203263
instance GEq TR.TypeRep where
204264
geq = testEquality
@@ -321,6 +381,25 @@ instance (GCompare a, GCompare b) => GCompare (Product a b) where
321381
GEQ -> GEQ
322382
GGT -> GGT
323383

384+
#if MIN_VERSION_base(4,6,0)
385+
-- | @since 1.0.4
386+
instance (GCompare f, GCompare g) => GCompare (f :+: g) where
387+
gcompare (L1 x) (L1 y) = gcompare x y
388+
gcompare (L1 _) (R1 _) = GLT
389+
gcompare (R1 _) (L1 _) = GGT
390+
gcompare (R1 x) (R1 y) = gcompare x y
391+
392+
-- | @since 1.0.4
393+
instance (GCompare a, GCompare b) => GCompare (a :*: b) where
394+
gcompare (x :*: y) (x' :*: y') = case gcompare x x' of
395+
GLT -> GLT
396+
GGT -> GGT
397+
GEQ -> case gcompare y y' of
398+
GLT -> GLT
399+
GEQ -> GEQ
400+
GGT -> GGT
401+
#endif
402+
324403
-------------------------------------------------------------------------------
325404
-- Some
326405
-------------------------------------------------------------------------------

0 commit comments

Comments
 (0)