aboutsummaryrefslogtreecommitdiff
path: root/ch05_05.3-iii.hs
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2025-01-03 11:01:20 -0800
committerPaul Oliver <contact@pauloliver.dev>2025-01-05 09:59:10 -0800
commit6a0d7f5c434c3564d0119befb6799fd77581050a (patch)
treef20bc998290211d2a895523417ad32e297b31af0 /ch05_05.3-iii.hs
InitialHEADmaster
Diffstat (limited to 'ch05_05.3-iii.hs')
-rw-r--r--ch05_05.3-iii.hs25
1 files changed, 25 insertions, 0 deletions
diff --git a/ch05_05.3-iii.hs b/ch05_05.3-iii.hs
new file mode 100644
index 0000000..b1c0865
--- /dev/null
+++ b/ch05_05.3-iii.hs
@@ -0,0 +1,25 @@
+import Data.Kind
+
+data HList (ts :: [Type]) where
+ HNil :: HList '[]
+ (:#) :: t -> HList ts -> HList (t ': ts)
+
+infixr 5 :#
+
+type family All (c :: Type -> Constraint) (ts :: [Type]) :: Constraint where
+ All c '[] = ()
+ All c (t ': ts) = (c t, All c ts)
+
+instance All Eq ts => Eq (HList ts) where
+ HNil == HNil = True
+ (a :# as) == (b :# bs) = a == b && as == bs
+
+-- Exercise 5.3-iii
+-- Rewrite the `Ord` and `Show` instances in terms of `All`:
+instance (All Eq ts, All Ord ts) => Ord (HList ts) where
+ compare HNil HNil = EQ
+ compare (a :# as) (b :# bs) = compare a b <> compare as bs
+
+instance All Show ts => Show (HList ts) where
+ show HNil = "HNil"
+ show (a :# as) = show a <> " :# " <> show as