Skip to content

Can't derive TYPE rep instances

Summary

Deriving fails when we have TYPE rep, not Type

{-# Language DerivingStrategies         #-}
{-# Language GeneralizedNewtypeDeriving #-}
{-# Language KindSignatures             #-}
{-# Language MagicHash                  #-}
{-# Language PolyKinds                  #-}
{-# Language UnliftedNewtypes           #-}

import GHC.Exts (TYPE, RuntimeRep(IntRep), Int#, (+#))
import Data.Coerce

class Num# (a# :: TYPE rep) where
 add# :: a# -> a# -> a#

instance Num# Int# where
 add# = (+#)

-- • Cannot derive well-kinded instance of form ‘Num# (IdInt# ...)’
--     Class ‘Num#’ expects an argument of kind ‘*’
-- • In the newtype declaration for ‘IdInt#’
newtype IdInt# = IdInt# Int#
 deriving
 newtype Num#

deriving works for a levity-polymorphic Id#

newtype Id# (a# :: TYPE rep) = Id# a#
 deriving
 newtype Num#

but sadly only for @LiftedRep

> :set -fprint-explicit-kinds
> :i Num#
..
instance Num# @'LiftedRep a# =>
         Num# @'LiftedRep (Id# @'LiftedRep a#)

Proposed improvements or changes

The first one should be derived at TYPE IntRep

instance Num# (IdInt# :: TYPE IntRep) where
 add# :: IdInt# -> IdInt# -> IdInt#
 add# = coerce (add# @IntRep @Int#)

but the second one wouldn't work for all rep, how can we get it to work

-- Cannot use function with levity-polymorphic arguments:
--   coerce :: (a# -> a# -> a#) -> Id# a# -> Id# a# -> Id# a#
-- Levity-polymorphic arguments:
--   Id# a# :: TYPE rep
--   Id# a# :: TYPE rep^[[0m^[[0m
instance Num# a# => Num# (Id# a# :: TYPE rep) where
 add# :: Id# a# -> Id# a# -> Id# a#
 add# = coerce (add# @rep @a#)

Environment

  • GHC version used: 8.10.0.20191123
Edited by Icelandjack
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information