这是一个哲学问题,但我希望能够通过官方文档或“上帝的话”来回答(阅读:SPJ)。 Haskell委员会选择以类型类型的形式需要显式接口而不是基于模式匹配的更统一的解决方案,是否有特定的原因?为什么类型类而不是模式匹配?
举个例子,拿Eq
:
class Eq a where
(==), (/=) :: a -> a -> Bool
x == y = not $ x /= y
x /= y = not $ x == y
instance Eq Int where
(==) = internalIntEq
为什么我们不能做这样的事情,而不是(承担与伪哈斯克尔):
(==), (/=) :: a -> a -> Bool
default x == y = not $ x /= y -- 1
default x /= y = not $ x == y
(Int a) == (Int b) = a `internalIntEq` b -- 2
也就是说,如果哈斯克尔是到允许普通数据类型的模式匹配,则:
程序员可以创建特设班,即
instance
是隐式的(2)类型仍然可以推断和静态匹配(
SupportsEqualsEquals a => ...
)默认实现会来“免费”
类可以随时可以扩展而不会破坏任何东西
需要一种方法来指定默认模式(1),尽管在其他s,总是匹配最后一个。这些假设的功能是否与Haskell内在的特性相冲突?正确推断类型会变得困难还是不可能?这看起来像是一个强大的功能,与Haskell的其他部分相得益彰,所以我认为这是一个很好的理由,我们不要这样做。这种ad-hoc多态性机制简直就是也是 ad-hoc?
我不是很精通,但我认为一个主要问题是,你失去parametricity,从而自由定理:你知道什么是'ID :: A - >了'或'FST ::(一, b) - > a'仅仅通过它们的类型签名来完成,因为它们只有参数多态性。如果你有某种类型的机制,那么你失去了参数。例如,'a - > a - > Bool'只允许Haskell中的两个(全部)实现('const $ const True'和'const $ const False');如果你有typecase,那么你失去了这个保证。 – 2012-02-02 04:04:32
@ AntalS-Z:只要确保我理解正确。你是说我可以声明'id :: a - > a',然后定义id(Int i)= i + 1'?因为情况并非如此:后一种定义将是'SupportsPlus a => a - > a',这是不兼容的。 – 2012-02-02 04:11:01
这就是你的问题听起来的样子;您的'(==)'的类型签名以'a - > a - > Bool'的形式给出。如果你必须指定一个“type class”'SupportsEquals',那么看起来你所做的一切都是交易语法---我不明白为什么它*不同*。我不认为它可以表达多参数类型类,函数依赖关系或关联类型,尽管它们当然不在原始计划中。事实上,它甚至可以表达更高级的类型类吗?你怎么知道'return :: a - > m a'应该是'm'上的ad-hoc,而不是'a'? – 2012-02-02 04:22:26