Skip to content

With PolyKinds, `reifyRoles` function in template-haskell gives unnecessary roles

Summary

The result of function reifyRoles in template-haskell gives one more results of roles when PolyKinds language extension is on.

Steps to reproduce

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

data Proxy a = Proxy

This gives correct result:

> :m +Language.Haskell.TH
> :set -XTemplateHaskell
> $(reifyRoles ''Proxy >>= stringE.show)
"[PhantomR]"

And in GHCi, :i gives correct info

> :i Proxy
type role Proxy phantom
type Proxy :: * -> *
data Proxy a = Proxy
        -- Defined at Test.hs:4:1

However, with PolyKinds extension on

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-}

data Proxy a = Proxy

It gives

> :m +Language.Haskell.TH
> :set -XTemplateHaskell
> $(reifyRoles ''Proxy >>= stringE.show)
"[NominalR,PhantomR]"

In this case, GHCi also gives correct role for polymorphic Proxy type:

> :i Proxy
type role Proxy phantom
type Proxy :: forall k. k -> *
data Proxy a = Proxy
        -- Defined at Test.hs:5:1

Expected behavior

The result returned by reifyRoles should be [PhantomR], just the same as the case without PloyKinds extension.

It seems that the results contain the roles of polymorphic kinds, however, I think we do not have kind role in GHC. If we add data Proxy2 a b = Proxy2

The reified role will be:

> $(reifyRoles ''Proxy2>>= stringE.show)
"[NominalR,NominalR,PhantomR,PhantomR]"

In this way, we need to know the kind in order to know what role is the type parameter of Proxy2 respectively.

Environment

  • GHC version used: 9.0, 8.10

Optional:

  • Operating System: Windows 10 Pro
  • System Architecture: amd64
Edited by songzh
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information