Haskell:与lambda函数一起使用时了解map函数

时间:2019-06-14 01:48:43

标签: haskell functional-programming higher-order-functions

我有以下两个Haskell表达式:

map (\f x -> f x 5) [(-),(+),(*)]
map (\f x -> f 5 x) [(-),(+),(*)]

我正在尝试确定以上任一表达式是否等效于以下表达式:

map ($ 5) [(-),(+),(*)]

我试图了解前两个表达式之间的区别。 由于对于这两个表达式,只有一个参数传递给lambda函数(例如,运算符),因此该函数将被部分应用。

说第一个表达式的结果列表中的元素将是正确的吗?

(1)- x 5 = (- x) 5

(2)+ x 5 = (+ x) 5

(3)* x 5 = (* x) 5

第二个表达式:

(1)- 5 x = (- 5) x

(2)+ 5 x = (+ 5) x

(3)* 5 x = (* 5) x

但是,我认为这两个表达式都不等于map ($ 5) [(-),(+),(*)]。这是因为(- x) 5(其中x是数字)在GHCI中给出错误,并且是无效的表达式。同样,(- 5) x也给出错误。 另一方面,映射($ 5)[(-)]产生一个函数,该函数接受一个数字并将其从5中减去。 这个推理正确吗?任何见解都会受到赞赏。

1 个答案:

答案 0 :(得分:4)

(- 5) 5发出错误,因为前缀减号在语言语法中是一种特殊情况:(- 5)表示减号5,即数字,而不是减去5的函数(另请参见:{{3 }})。既然如此,我将专注于(+)情况,这并不例外。

在第二个表达式map (\f x -> f 5 x) [(-),(+),(*)]中,结果列表的第二个元素将是:

(\f x -> f 5 x) (+)

手动评估此类内容时,请务必注意不要混淆运算符的前缀,中缀和分段使用。这里的应用程序给出了...

\x -> (+) 5 x  -- Prefix syntax (note the parentheses around the operator)

...相当于...

\x -> 5 + x  -- Infix syntax

...以及:

\x -> (5 +) x  -- Left section
\x -> (+ x) 5  -- Right section

(5 +)          -- Left section, pointfree

因此,相对于您的问题,在使用运算符的infix使用之后进行模式化的部分应该是相反的方式。对于map ($ 5) [(-),(+),(*)],它等效于第二个表达式map (\f x -> f 5 x) [(-),(+),(*)]。您可以通过使用($) f x = f x找出($ 5)右边部分是什么的事实来确认这一点。