Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why can't I get this code to work, typed verbatim from "Thinking With Types"

In Sandy Maguire’s "Thinking With Types", Page 69, there is the following code

{-# LANGUAGE ConstraintKinds      #-}
{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE GADTs                #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE TypeApplications     #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE InstanceSigs #-}

instance (Eq t, Eq (HList ts)) => Eq (HList (t ': ts)) where 
  (a :# as) == (b :# bs) = a == b && as == bs 

The definition of HList is

data HList (ts :: [Type]) where
  HNil :: HList '[]
  (:#) :: t-> HList ts -> HList(t':ts)
infixr 5 :#

The above instance produces the following error

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    • Couldn't match expected type ‘t1’ with actual type ‘t2’
      ‘t2’ is a rigid type variable bound by
        a pattern with constructor:
          :# :: forall t (ts :: [Type]) t'.
                t -> HList ts -> HList ((':) @Type t' ts),
        in an equation for ‘==’
        at src/Types/ChapterFive.hs:41:17-23
      ‘t1’ is a rigid type variable bound by
        a pattern with constructor:
          :# :: forall t (ts :: [Type]) t'.
                t -> HList ts -> HList ((':) @Type t' ts),
        in an equation for ‘==’
        at src/Types/ChapterFive.hs:41:4-10
    • In the second argument of ‘(==)’, namely ‘b’
      In the first argument of ‘(&&)’, namely ‘a == b’
      In the expression: a == b && as == bs
    • Relevant bindings include
        b :: t2 (bound at src/Types/ChapterFive.hs:41:17)
        a :: t1 (bound at src/Types/ChapterFive.hs:41:4)
   |
41 |   (a :# as) == (b :# bs) = a == b && as == bs 

So, I tried giving it an explicit type

instance (Eq t, Eq (HList ts)) => Eq (HList (t ': ts)) where 
  (==) :: forall t (ts :: [Type]).(Eq t, Eq (HList ts)) => HList ((':) @Type t ts) -> HList ((':) @Type t ts) -> Bool
  (a :# as) == (b :# bs) = a == b && as == bs 

But this produces a new error

    Operator applied to too few arguments: :
   |
41 |   (==) :: forall t (ts :: [Type]).(Eq t, Eq (HList ts)) => HList ((':) @Type t ts) -> HList ((':) @Type t ts) -> Bool

I tried changing the code as follows

instance (Eq t, Eq (HList ts)) => Eq (HList (t ': ts)) where 
  (==) :: forall t (ts :: [Type]).(Eq t, Eq (HList ts)) => HList ((:#) @Type t ts) -> HList ((:#) @Type t ts) -> Bool
  (a :# as) == (b :# bs) = a == b && as == bs 

This yielded the following error

src/Types/ChapterFive.hs:41:107: error:
    • Expected kind ‘HList ts1’, but ‘ts’ has kind ‘[Type]’
    • In the third argument of ‘(:#)’, namely ‘ts’
      In the first argument of ‘HList’, namely ‘((:#) @Type t ts)’
      In the type signature:
        (==) :: forall t (ts :: [Type]). (Eq t, Eq (HList ts)) =>
                                         HList ((:#) @Type t ts) -> HList ((:#) @Type t ts) -> Bool
   |
41 |   (==) :: forall t (ts :: [Type]).(Eq t, Eq (HList ts)) => HList ((:#) @Type t ts) -> HList ((:#) @Type t ts) -> Bool

>Solution :

I get this working when writing the GADT as:

data HList (ts :: [*]) where
  HNil :: HList '[]
  (:#) :: t-> HList ts -> HList(t ': ts)  -- 🖘 space between t and ':
infixr 5 :#

otherwise it is probably interpreted as t' followed by :.

In order to let this work, you should also makes HNil an instance of Eq:

instance Eq (HList '[]) where 
  _ == _ = True
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading