aboutsummaryrefslogtreecommitdiff
path: root/ch05_05.3-i_ii.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-i_ii.hs
InitialHEADmaster
Diffstat (limited to 'ch05_05.3-i_ii.hs')
-rw-r--r--ch05_05.3-i_ii.hs34
1 files changed, 34 insertions, 0 deletions
diff --git a/ch05_05.3-i_ii.hs b/ch05_05.3-i_ii.hs
new file mode 100644
index 0000000..3d73229
--- /dev/null
+++ b/ch05_05.3-i_ii.hs
@@ -0,0 +1,34 @@
+import Data.Kind
+
+data HList (ts :: [Type]) where
+ HNil :: HList '[]
+ (:#) :: t -> HList ts -> HList (t ': ts)
+
+infixr 5 :#
+
+instance Eq (HList '[]) where
+ HNil == HNil = True
+
+instance (Eq t, Eq (HList ts)) => Eq (HList (t ': ts)) where
+ (a :# as) == (b :# bs) = a == b && as == bs
+
+-- Exercise 5.3-i
+-- Implement `Ord` for `HList`:
+instance Ord (HList '[]) where
+ compare HNil HNil = EQ
+
+-- I always forget `Ord` is a monoid. This version is less elegant, but works
+-- just as well as Sandy's:
+instance (Ord t, Ord (HList ts)) => Ord (HList (t ': ts)) where
+ compare (a :# as) (b :# bs) =
+ case compare a b of
+ EQ -> compare as bs
+ other -> other
+
+-- Exercise 5.3-ii
+-- Implement `Show` for `HList`:
+instance Show (HList '[]) where
+ show HNil = "HNil"
+
+instance (Show t, Show (HList ts)) => Show (HList (t ': ts)) where
+ show (a :# as) = show a <> " :# " <> show as