aboutsummaryrefslogtreecommitdiff
path: root/ch05_05.3-i_ii.hs
blob: 3d7322985ae0d24d34f61283f38e721cb7d0c0fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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