首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有多参数类型类的类型统一

具有多参数类型类的类型统一
EN

Stack Overflow用户
提问于 2014-07-03 09:35:15
回答 1查看 314关注 0票数 5
代码语言:javascript
运行
复制
{-# LANGUAGE MultiParamTypeClasses #-}
class Coerce a b where coerce :: a -> b
instance Coerce a a where coerce a = a

现在,这将无法工作:coerce 0 :: Int,但是如果实例被替换为此,则表达式工作:

代码语言:javascript
运行
复制
instance a ~ b => Coerce a b where coerce x = x

为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-03 10:09:23

我可以告诉你为什么第一个不起作用。

可以为任何可能的类型定义Coercecoerce 0 :: Int被解析为(coerce 0) :: Int。因此,您已经用类型注释来修复coerce :: a -> b中的coerce :: a -> b,而不是a

数字文字是多态的,所以0Num 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的任何可能调用(因此您不能编写任何其他不重叠的实例)。只有在选择实例之后才应用a ~ b约束。

因为您有一个与任何内容匹配的实例,所以为coerce 0 :: Int选择一个实例是没有问题的,尽管我们仍然存在不知道0是什么类型的问题。但是在实例选择之后,我们现在有了附加的约束a ~ Int,它允许为所有事物分配明确的类型。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24550088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档