我有以下两个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中减去。
这个推理正确吗?任何见解都会受到赞赏。
答案 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)
右边部分是什么的事实来确认这一点。