类型同义词中的模式匹配/内部类型参数的类型同义词

时间:2013-01-24 03:12:07

标签: haskell types pattern-matching synonym type-parameter

我的代码中有类似于此类的内容。我的情况是将'作为另一个参数添加到类Foo。

是没有意义的
class Foo a where
    type FCtx a a' :: Constraint
    type FCtx a a' = ()

    f :: (FCtx a a') => a -> a'

data D b = D b

instance (Integral b) => Foo (D b) where
    -- the next line does not compile because b' does not appear on the LHS
    type FCtx (D b) a' = (a' ~ D b', Integral b') 

    f (D x) = D $ fromIntegral x

对于Foo特定实例,我希望a'以这种方式关联。我想出这个工作的唯一方法就是添加一个“虚拟”类,其中包含一个“明显”类型的同义词:

class DClass d where
   type DType d

instance DClass (D b) where
    type DType (D b) = b

Foo实例现在变为:

instance (Integral b) => Foo (D b) where
    type FCtx (D b) a' = (a' ~ D (DType a'), Integral (DType a'))
    f (D x) = D $ fromIntegral x

问题是我必须为我的特定数据类型创建一个完整的类(和实例),以表达(D b)确定b的类型同义词/功能依赖。我不会有这个类的任何其他实例,因为我始终希望DType a'表示D b的类型参数。

我想做的是:

type DParam (D b) = b

instance (Integral b) => Foo (D b) where
     type FCtx (D b) a' = (a' ~ D (DParam a'), Integral (DParam a'))
     f (D x) = D $ fromIntegral x

或甚至可能更好地表达此约束而不使用类型同义词。愚蠢的是,我应该被迫创建一个带有单个实例的类型同义词的(开放)类来实现这一点,并且其他人可能创建我不想要的新实例是不安全的。

至少,是不是会有一些规范的方式将“模式匹配类型同义词”转换为上面的类/实例DClass

1 个答案:

答案 0 :(得分:5)

重量稍轻,使用类型系列:

type family DParam d :: *
type instance DParam (D b) = b

不确定你现在能不能做得更好......