使用多参数类型类型进行统一

时间:2014-07-03 09:35:16

标签: haskell

{-# LANGUAGE MultiParamTypeClasses #-}
class Coerce a b where coerce :: a -> b
instance Coerce a a where coerce a = a

现在,这不起作用:coerce 0 :: Int 但是如果实例替换为this,则表达式可以工作:

instance a ~ b => Coerce a b where coerce x = x

为什么?

1 个答案:

答案 0 :(得分:10)

我可以告诉你为什么第一个没有工作。

可能会为任何类型的定义

Coercecoerce 0 :: Int被解析为(coerce 0) :: Int。因此,您已使用类型注释修复b中的coerce :: a -> b,而不修复a

数字文字是多态的,因此0的类型为Num a => a。那不行;没有匹配Coerce a Int的实例。可能有Coerce Double IntCoerce Complex Int等,因此知道bInt并不足以推断0Int }。我们需要说coerce (0 :: Int) :: Int来修复这两个类型参数。

相信第二个可行,因为实例声明的约束不用于帮助解析类型类。 instance a ~ b => Coerce a b与您编写instance Coerce a b完全匹配。即这是最常见的实例(用于类型类解析),它可以很好地匹配对coerce的任何可能调用(因此您不能编写任何其他非重叠实例)。 {/ 1}}约束仅在选择实例后才会应用

由于您有一个匹配任何内容的实例,因此选择a ~ b的实例没有问题,即使我们仍然遇到不知道coerce 0 :: Int的类型的问题。但是在实例选择之后,我们现在有了额外的约束0,它允许将明确的类型分配给所有内容。