Skip to content

Wrong error message for type argument with an identifier that occupies both the term and type namespace, without the `type` keyword

Passing type arguments without the type keyword to VDQ functions results in the wrong error message.

As an example:

class Cardinality a where
  cardinality :: Maybe Int

instance Cardinality Bool where
  cardinality = Just 2

instance Cardinality () where
  cardinality = Just 1

instance Cardinality Void where
  cardinality = Just 0

instance (Cardinality a, Cardinality b) => Cardinality (a -> b) where
  cardinality = (^) <$> (cardinality @b) <*> (cardinality @a)


card :: forall a -> Cardinality a => Maybe Int
card (type x) = cardinality @x

-- These would typecheck 
t1 = card Bool 
t2 = card (type Bool)
t3 = card (type ())

-- t4 results in a weird error message
t4 = card ()
{-
<interactive>:233:1-4: error: [GHC-39999]
    * No instance for `Cardinality '()' arising from a use of `card'
    * In the expression: card ()
      In an equation for `it': it = card ()
-}

-- We can clearly see that there is an instance for ()

Now, strangely, if we create a type synonym for (), and pass it to card, typechecking succeeds.

type Unit = ()
t5 = card Unit -- typechecks

But now, if we create some type that has Unit as a data constructor, we get the same error message:

data Foo = Unit | FC
t6 = card Unit -- fails 

{-
<interactive>:247:1-4: error: [GHC-39999]
    * No instance for `Cardinality 'Unit' arising from a use of `card'
    * In the expression: card Unit
      In an equation for `it': it = card Unit
-}

I think the term-2-type mapping fails when the identifier occupies both the term and type namespace at the same time.

GHC version used: 9.9.20231126

Edited by Artin Ghasivand
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information