haskell - 声明函数类型时语法不一致
问题描述
如果我正在创建一个函数,让我们举一个最简单的例子:
add x y = x + y
如果我想在之前添加一个函数类型声明,为了清楚起见
add :: (Int, Int) -> Int
add x y = x + y
我收到一个编译错误:
“无法将预期类型 'Int' 与实际类型 '(Int, Int) -> (Int, Int)' 匹配”。
“'add' 的方程有两个参数,但它的类型'(Int,Int)-> Int'只有一个“
但如果我将其纠正为
add :: (Int, Int) -> Int
add (x, y) = x + y
来自其他语言,我实际上认为使用带括号的第二种形式更清楚,但在我看来,两种方式都应该有效
1 - 不以第一种方式工作的原因是什么?
2 - 我发现错误消息完全令人困惑,所以,也许,错误发生的另一个原因我不明白
解决方案
第一种方式不工作的原因是什么?
在第一个表达式中,您的类型表示它需要一个 2 元组作为单个参数,并返回两项之和。但是在函数的“主体”中,您指定add x y = x + y
因此构造一个函数,该函数接受一个参数,该参数x
将返回一个函数,该函数将接受一个y
映射到x + y
.
在 Haskell 中,所有函数都采用一个参数。实际上,您的add
函数采用一个参数x
。它的缩写:
add x = \y -> x + y
因此,它返回一个函数,该函数将接受一个参数y
,然后映射y
到x + y
. 如果您因此构造一个函数f = add 2
,那么f
将获取参数y
,并将其映射到2 + y
。
箭头是右结合运算符。这意味着Int -> Int -> Int
是 的缩写Int -> (Int -> Int)
,因此它是将 a 映射Int
到另一个函数的函数。
您可以看到像 Java 这样的语言的语法,它们f (x, y)
基本上调用函数f
时使用一个对象:一个 2 元组,其中x
和y
作为它的两个元素。
推荐阅读
- html - 文本阴影不会在 DIV 内触发,但会在 BODY 中触发
- angular - Angular 9 中的 PWA 实现
- ios - PanGesture 事件干扰洗涤器清理事件
- android - android studio logcat中字母的含义是什么?
- laravel - Laravel 6.2 whereHasMorph 没有返回预期值
- haskell - 计算 `map 的类型。文件夹`
- ios - Expokit:未定义的方法“target_installation_results”
- javascript - 获取对象数组,然后将其显示在我的组件中
- ios - 添加自定义弹出窗口不会填充完整视图 iOS、Swift
- sql - 如何使用实体框架更新多对多表