Haskell 谁能解释这个哈斯克尔难题?
我知道,使用。运算符链一起起作用,如下所示:Haskell 谁能解释这个哈斯克尔难题?,haskell,Haskell,我知道,使用。运算符链一起起作用,如下所示: isLessThanZero x | x < 0 = True | otherwise = False (isLessThanZero . negate) 3 -- Produces True 但如果我要做的事情是: (subtract . negate) 1 2 -- 3 negate $ subtract 1 2 -- -1 这里的结果是不同的,这没有意义,因为这两个函数接受不同数量的参数。使用时,否定函数检查数字是否为
isLessThanZero x
| x < 0 = True
| otherwise = False
(isLessThanZero . negate) 3 -- Produces True
但如果我要做的事情是:
(subtract . negate) 1 2 -- 3
negate $ subtract 1 2 -- -1
这里的结果是不同的,这没有意义,因为这两个函数接受不同数量的参数。使用
时,否定
函数检查数字是否为负数,但提供了两个参数。这可能意味着表达式是左关联的
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应该如何应对呢?在Haskell上,函数是curried的,所以:
f :: a -> b -> c
同:
f :: a -> (b -> c)
因此,在计算F12
时,首先将a
应用于f
,得到类型为b->c
的函数。然后应用b
,得到c
现在,让我们遵循以下类型:
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Prelude> :t negate
negate :: Num a => a -> a
Prelude> :t subtract
subtract :: Num a => a -> a -> a
Prelude> :t (subtract.negate)
(subtract.negate) :: Num b => b -> b -> b
那么,(subtract.negate)2的类型是什么
Prelude> :t (subtract.negate) 1
(subtract.negate) 1 :: Num b => b -> b
正如你所看到的,negate
得到了一个1
并给出了-1
,但是subtract
得到了-1
,并给出了Int->Int
。然后你把2
应用到Int->Int
上,得到3
简而言之,()
始终是右关联的,并采用(b->c)
和(a->b)
。唯一的棘手部分是,<代码> C <代码>本身可以是<代码>(D -> E)。 < P> Haskell方法是考虑所有函数作为一个参数,并返回一个值,即使对于具有多个参数的函数也是如此。
因此,subtract
函数的签名为:
subtract :: Num a => a -> a -> a
(.) :: (y -> z) -> (x -> y) -> x -> z
也可以看到:
subtract :: Num a => a -> (a -> a)
接受一个数值参数并返回一个接受一个数值并返回一个数值的函数
考虑到()
,其签名为:
subtract :: Num a => a -> a -> a
(.) :: (y -> z) -> (x -> y) -> x -> z
它有两个函数,一个函数返回一个函数
如果将其应用于(subtract.negate)
,则具有以下签名:
(subtract . negate) :: Num a => (a -> (a -> a)) -> (a -> a) -> (a -> (a -> a))
其中:
x = a
y = a
z = a -> a
此函数的签名是完全有效的
请注意,subtract 12
的作用类似于2-1
(subtract.negate)
函数是一个取一个数值的函数,对其求反并返回一个取另一个数值的函数,该数值将从中减去被求反的数值
还要注意,否定(减去12)
等于-1
,而不是3
这可能意味着表达式是左关联的
negate (subtract 1 2) -- -1
(subtract . negate) 1 2 -- 3
我不明白你说的“少联想”是什么意思
函数应用程序是左关联的,这意味着abc
解析为(ab)c
组合的定义如下:(a.b)c=a(bc)
因此
另一个表达式是这样的(带有a$b=ab
):
那么,函数组合和函数应用程序是否都是右关联的(从右到左)?对于
来说,这并不重要,因为是一个。(b.c)=(a.b)。c
$
是右关联的,因为a$b$c
解析为a$(b$c)
。您可以在GHCi::i中找到具有:i的任何运算符的关联性和优先级。
返回[…]infixr 9.
。