我知道使用 . 运算符可以将函数链接在一起,例如:
isLessThanZero x
| x < 0 = True
| otherwise = False
(isLessThanZero . negate) 3 -- Produces True
或者使用美元符号$:
getNegNumbers x = map (*x) [-1, -2, -3]
filter isLessThanZero $ getNegNumbers 2 -- Produces [-2, -4, -6]
但是如果我想要做类似于这样的事情:
(subtract . negate) 1 2 -- 3
negate $ subtract 1 2 -- -1
这里的结果不同,这是没有意义的,因为这两个函数接受的参数数量不同。使用
.
,negate
函数检查一个数是否为负数,但提供了两个参数。这可能意味着表达式是左关联的。negate (subtract 1 2) -- -1
(subtract . negate) 1 2 -- 3
但这很令人困惑,因为在第一个示例中:
(isLessThanZero . negate) 3
表达式产生了True,这意味着函数negate首先被执行,然后调用isLessThanZero。但在最新的示例中,似乎是先调用subtract,然后再调用negate。所以我不确定这里到底发生了什么。但更令人困惑的是:
subtract 1 2 -- Produces 1!
这意味着整个表达式:
(subtract . negate) 1 2 -- Produces 3!
函数链使用时的副作用。
我的理论是这样分解的:
我们知道2 -(-1)= 3。 所以,表达式仍然是向右结合的..我认为。 negate
仍然首先被调用,就像前面的例子一样,只是它影响第一个参数,而不是两个参数,这是有道理的,因为negate只接受一个参数,我们根本不需要对函数进行映射。
那么,当使用参数数量不同的函数进行链接时,Haskell应该如何响应呢?
:i
命令来查找任何操作符的结合性和优先级::i .
会返回[...] infixr 9 .
。 - David Young