gpt4 book ai didi

haskell - 为什么使用模式匹配构造的函数具有 Eq 类型约束,但在使用数据构造函数时没有?

转载 作者:行者123 更新时间:2023-12-04 09:57:47 25 4
gpt4 key购买 nike

为什么 ghci 列出 equality type此函数的类型签名中的约束matchInt我通过模式匹配构建的:

$ 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 不需要它? ?在这里,我来到我的关键点:不要 两个 matchIntmatchDataInt必须针对 1 进行测试才能使模式匹配运行?

最佳答案

语法 matchInt是建立在模式匹配之上的,但是这里的模式匹配是一种错觉。 1不是数据构造函数。数字文字被重载。 1相当于fromInteger #1在哪里 #1Integer 类型的非重载 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 IntNum Int , 一切都好。

这就是你的第二个例子中发生的事情。您匹配的类型已知为 Int ,不是因为显式类型签名,而是因为它是从 Y Int 推断出来的 Z 的替代品.又来了 Int已经拥有所有需要的实例。

关于haskell - 为什么使用模式匹配构造的函数具有 Eq 类型约束,但在使用数据构造函数时没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46924456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com