我有以下数据类型:
{-# LANGUAGE GADTs, KindSignatures, ScopedTypeVariables, DataKinds #-}
import GHC.TypeLits
import Unsafe.Coerce
data Var (i :: Nat) where
    Var :: (Num a, Integral a) => a -> Var i
    {- other constructors .... -}
然后我有一个Num实例:
instance Num (Var i) where
    (Var a) + (Var b) = Var (a + b)
当然,这是行不通的。该类型a被构造函数隐藏,因为 的类型Var是forall (i :: Nat) a. Num a => a -> Var i。另请注意,Var构造函数不打算直接使用;Vars 由保证Var i0 ~ Var i1 => a0 ~ a1. Var 的类型不能是Var i a; 关键是对用户隐藏类型。
我怎样才能告诉类型系统,我已经“证明”的是真实的,即Var i0 ~ Var i1 => a0 ~ a1. 目前我正在使用unsafeCoerce:
(Var (a :: n)) + (Var b) = Var (a + (unsafeCoerce b :: n))
我意识到这unsafeCoerce是在两个类型相等的断言中,但我想尝试在类型级别上做出这个断言,以便导出构造函数不是不安全的。不安全我的意思是以下是可能的:
>instance Show (Var i) where {show (Var a) = "Var " ++ show a}
>import Data.Word
>Var (1000 :: Word16) + Var (255 :: Word8)
Var 1255
>Var (255 :: Word8) + Var (1000 :: Word16)
Var 231