内容简介:翻译自:https://stackoverflow.com/questions/46924456/why-does-a-function-constructed-with-pattern-matching-have-the-eq-type-constrain
约束:
$ghci GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help Prelude> :{ Prelude| matchInt 1 = 3 Prelude| matchInt _ = 4 Prelude| :} Prelude> matchInt 1 3 Prelude> matchInt 22 4 Prelude> :t matchInt matchInt :: (Eq a, Num a, Num p) => a -> p
相反,当使用简单的数据构造函数时,没有相等类型约束.
$ghci GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help Prelude> data Z = Y Int Prelude> :{ Prelude| matchDataInt (Y 1) = 3 Prelude| matchDataInt _ = 4 Prelude| :} Prelude> matchDataInt (Y 1) 3 Prelude> matchDataInt (Y 22) 4 Prelude> :t matchDataInt matchDataInt :: Num p => Z -> p
实际上Z的实例无法比较:
Prelude> Y 22 == Y 33 <interactive>:11:1: error: • No instance for (Eq Z) arising from a use of ‘==’ • In the expression: Y 22 == Y 33 In an equation for ‘it’: it = Y 22 == Y 33
那么,为什么matchInt函数列表相等作为类型约束而不是函数matchDataInt?
这与 question 有关.但是,如果matchInt需要进行相等测试,那么为什么matchDataInt不需要它?在这里,我来到我的关键点:不是matchInt和matchDataInt都必须测试1对模式匹配操作?
Syntactically matchInt是基于模式匹配构建的,但这里的patern匹配是一种幻觉. 1不是数据构造函数.数字文字被重载. 1相当于fromInteger#1,其中#1是Integer类型的非重载litteral(在标准Haskell中不可表达).你无法真正模仿这种事情.
所以编译器允许你在语法上写出模式匹配,但这种表示法真的表示一个守护:
matchInt 1 = ... -- what is written matchInt x | x == fromInteger #1 = ... -- what it really means
由于未明确给出matchInt的类型,因此推断出它.它是一个函数,因此类型是a-> b的一些细化.对fromInteger的调用产生了约束Num a,并且对==的调用产生了约束Eq a,这就是我们可以告诉的所有关于a的问题.
如果OTOH我们给函数一个明确的签名,比方说
matchInt :: Int->Int
那么我们不需要推断类型,只检查它是否满足约束条件.由于Int满足Eq Int和Num Int,一切都很好.
这就是你的第二个例子中正在发生的事情.您匹配的类型已知为Int,不是因为显式类型签名,而是因为它是从Z的Y Int替代推断出来的.这里Int已经拥有所有需要的实例.
翻译自:https://stackoverflow.com/questions/46924456/why-does-a-function-constructed-with-pattern-matching-have-the-eq-type-constrain
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Java构造函数与普通函数用法详解
- 构造函数、原型、原型链、继承
- Vue源码: 构造函数入口
- Hashmap源码解析-构造函数
- JavaScript 构造函数的继承
- Swift学习之构造函数与析构函数
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。