我一直在缓慢地移植llvm包以使用数据类型、类型族和类型 nats,并在尝试通过引入由其参数化的新类型来删除用于对值(ConstValue
和)进行分类的两种新类型时遇到了一个小问题恒常性。Value
Value
CallArgs
仅接受Value 'Variable a
参数并提供将 a 转换为 a 的Value 'Const a
函数Value 'Variable a
。我想概括CallArgs
一下,允许每个参数是'Const
or 'Variable
。这是否可以使用类型族以某种方式对其进行编码?我认为这可能与fundeps是可行的。
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
data Const = Const | Variable
data Value (c :: Const) (a :: *)
type family CallArgs a :: *
type instance CallArgs (a -> b) = forall (c :: Const) . Value c a -> CallArgs b
type instance CallArgs (IO a) = IO (Value 'Variable a)
...无法编译:
/tmp/blah.hs:10:1: 非法多态或限定类型: forall (c :: Const)。价值约 在“CallArgs”的类型实例声明中
以下解决方案有效(相当于遗留代码),但需要用户强制转换每个常量Value
:
type family CallArgs' a :: *
type instance CallArgs' (a -> b) = Value 'Variable a -> CallArgs' b
type instance CallArgs' (IO a) = IO (Value 'Variable a)