gpt4 book ai didi

haskell - $ 函数在 haskell 中实际上做了什么?

转载 作者:行者123 更新时间:2023-12-02 09:53:52 25 4
gpt4 key购买 nike

我知道

$ :: (a->b) -> a -> b
f $ x = f x

直觉上我觉得,1. $ 延迟对其左侧函数的求值2. 评估其右边的内容3. 将其左侧的结果传送至其右侧。

这对我来说非常有意义,

ghci> length $ [1..5]
5
ghci> ($) length [1..5]
5

我不明白的是为什么,

ghci> ($ [1..5]) length
5

从 $ 的类型来看,它的(第一个)参数不应该是一个函数吗?

最佳答案

这与解析有关。在 Haskell 中,您可以编写 (op arg),其中 op 是中缀运算符。这与 ((op) arg) 不同。您也可以编写 (arg op) !例如:

GHCi, version 7.0.3: http://www.haskell.org/ghc/  :? for help
Prelude> :t (+ 4)
(+ 4) :: Num a => a -> a
Prelude> :t (4 +)
(4 +) :: Num a => a -> a

也就是说,(+ 4) 是函数 \x -> x + 4(4 +) 是函数 \y -> 4 + y。在加法的情况下,这些是相同的函数,但现在这并不重要。

现在让我们在 $ 上尝试同样的技巧:

Prelude> :t ($ [1,2,3,4])
($ [1,2,3,4]) :: Num t => ([t] -> b) -> b

现在令人惊讶的是,我们得到了\f -> f $ [1,2,3,4]。我们也可以这样写

Prelude> :t (length $)
(length $) :: [a] -> Int

获取函数\l -> 长度$ l。但是这个怎么样:

Prelude> :t ($ length)
($ length) :: (([a] -> Int) -> b) -> b

这很奇怪,但也有道理!我们得到了 \f -> f $ length,即一个函数,它期望获得 f 类型的函数 ([a ] -> Int) -> b) 将应用于 length。还有第四种可能:

Prelude> :t ([1,2,3,4] $)

<interactive>:1:2:
Couldn't match expected type `a0 -> b0' with actual type `[t0]'
In the first argument of `($)', namely `[1, 2, 3, 4]'
In the expression: ([1, 2, 3, 4] $)

一切都应该如此,因为[1,2,3,4]不是一个函数。如果我们在括号中写入 $ 会怎样?那么它作为中缀运算符的特殊含义就消失了:

Prelude> :t (($) length)
(($) length) :: [a] -> Int

Prelude> :t (($) [1,2,3,4])
<interactive>:1:6:
Couldn't match expected type `a0 -> b0' with actual type `[t0]'
In the first argument of `($)', namely `[1, 2, 3, 4]'
In the expression: (($) [1, 2, 3, 4])

Prelude> :t (length ($))
<interactive>:1:9:
Couldn't match expected type `[a0]'
with actual type `(a1 -> b0) -> a1 -> b0'
In the first argument of `length', namely `($)'
In the expression: (length ($))

Prelude> :t ([1,2,3,4] ($))
<interactive>:1:2:
The function `[1, 2, 3, 4]' is applied to one argument,
but its type `[t0]' has none
In the expression: ([1, 2, 3, 4] ($))

所以,回答你的问题: $ [1,2,3,4] 被解析为 \f -> f $ [1,2,3,4] 因此将其应用于 length 是非常有意义的。然而 ($) [1, 2, 3, 4] 没有多大意义,因为 ($) 不被视为中缀运算符。

顺便说一句,$ 可以说“不做任何事情”。它主要用于更具可读性的输入,因为它的优先级较低,因此我们可以编写 f $ g $ h $ x 而不是 f (g (h x))

关于haskell - $ 函数在 haskell 中实际上做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15784841/

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