Function Haskell函数的应用
好吧,这是漫长的一天,我的大脑可能没有哈斯克尔水平的功能,但我就是无法理解“向你学习哈斯克尔”中的一个例子 该部分称为带有$的函数应用程序,下面是如何定义Function Haskell函数的应用,function,haskell,operators,partial-application,operator-sections,Function,Haskell,Operators,Partial Application,Operator Sections,好吧,这是漫长的一天,我的大脑可能没有哈斯克尔水平的功能,但我就是无法理解“向你学习哈斯克尔”中的一个例子 该部分称为带有$的函数应用程序,下面是如何定义$的示例: ($) :: (a -> b) -> a -> b f $ x = f x 到目前为止,一切都很清楚。我理解本节中的所有示例,但最后一个除外: ghci> map ($ 3) [(4+), (10*), (^2), sqrt] [7.0,30.0,9.0,1.7320508075688772] 在这里,我
$
的示例:
($) :: (a -> b) -> a -> b
f $ x = f x
到目前为止,一切都很清楚。我理解本节中的所有示例,但最后一个除外:
ghci> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
在这里,我们在函数列表中映射($3)
,并将这些函数的应用结果映射到3
。但这怎么可能呢
从第一个代码片段可以清楚地看出,第一个参数是一个函数,我们甚至可以编写:
*Main> ($) sqrt 4
2.0
现在($3)
是函数$
的部分应用,但是3
继续函数的位置!那么3
应该是一个函数还是什么
还有一个谜团:到底是什么?我知道
(+4)
是函数+
的部分应用,所以(4+
应该是函数4
的部分应用?胡说什么样的技巧在这里起作用?我想让你感到困惑的是操作员部分。这使您可以使用运算符的任一参数部分应用运算符,因此您可以使用运算符(+4)
和(4+)
,其中4
分别是+
的第二个参数和第一个参数。一个更清楚的例子可能是(“Hello”+)
与(++“world”)
,前者将“Hello”
前置到字符串的前面,而后者将“world”
追加到字符串的末尾
这与使用前缀形式的运算符(仅在其周围使用paren)形成对比。在本表中,以下内容等效:
> let join = (++)
> join "Hello, " "world"
"Hello, world"
> (++) "Hello, " "world"
"Hello, world"
在前缀形式中,将运算符视为普通函数,它依次接受其第一个参数和第二个参数。在运算符部分中,参数位于运算符的哪一侧很重要
因此,在您的示例中,部分应用了
($3)
,您可以将其减少为
map ($ 3) [(4+), (10*), (^2), sqrt]
[($ 3) (4+), ($ 3) (10 *), ($ 3) (^ 2), ($ 3) sqrt]
[4 + 3, 10 * 3, 3 ^ 2, sqrt 3]
[7.0, 30.0, 9.0, 1.7320508075688772]
($3)
和(+4)
不是部分应用程序-它们是操作员部分。部分应用程序看起来像($)3
或(+)4)
形式为
(?x)
(其中?
表示任意中缀运算符)的运算符部分绑定运算符的右操作数,即它等效于\y->y?x
。同样,运算符部分(x?
绑定左操作数,因此相当于部分应用程序。您对部分感到困惑。掌握节的概念的一个好方法是使用一个示例:
(<^>) :: Int -> Float -> Int
a <^> b = a
查看
a
和b
的类型如何因节不同而不同。可能重复“您将运算符视为正常函数”,我认为“运算符”在Haskell中是正常函数。@请标记它们在除应用程序语法之外的所有方面都是正常的。它们默认为中缀,而非运算符函数默认为前缀。当我说正规函数时,我指的是前缀函数。
λ> let a = (3 <^>)
λ> :t a
a :: Float -> Int
λ> let b = (<^> 3.0)
λ> :t b
b :: Int -> Int