我开始学习 Haskell,遇到了一个我无法理解的问题。我有一个用于从键值列表列表中查找值的方法(来自 this page ):
let findKey key xs = snd . head . filter (\(k,v) -> key == k) $ xs
我试着摆弄了一下,并决定以这种方式摆脱 $ 符号:
let findKey key xs = snd . head . filter (\(k,v) -> key == k) ( xs )
但是,它甚至不解析(过滤器应用于太多参数错误)。我读过 $ 符号用于简单地替换括号,我无法弄清楚为什么这种简单的代码更改是不好的。有人可以向我解释吗?
最佳答案
中缀运算符 ($)
只是“功能应用”。换句话说
f x -- and
f $ x
是相同的。由于在 Haskell 括号中仅用于消除优先级歧义(对于元组表示法和 a few other minor places, see comments ),我们还可以用其他几种方式编写上述内容
f x
f $ x
(f) x
f (x)
(f) (x) -- and even
(f) $ (x)
在每种情况下,上述表达式都表示相同的内容:“将函数
f
应用于参数 x
”。那么为什么有所有这些语法呢?
($)
有用有两个原因在第一种情况下,考虑以下深度右嵌套函数应用程序
f (g (h (i (j x))))
阅读这篇文章可能有点困难,知道你有正确数量的括号也有点困难。但是,它“只是”一堆应用程序,所以应该使用
($)
来表示这个短语。 .确实有 f $ g $ h $ i $ j $ x
有些人觉得这更容易阅读。更现代的风格还融入了
(.)
为了强调这个短语的整个左侧只是一个组合的函数管道 f . g . h . i . j $ x
正如我们在上面看到的,这个短语与
(f . g . h . i . j) x
有时更好读。
有时我们希望能够传递函数应用的想法。例如,如果我们有一个函数列表
lof :: [Int -> Int]
lof = [ (+1), (subtract 1), (*2) ]
我们可能想通过一个值来映射应用程序,例如应用数字
4
到每个功能> map (\fun -> fun 4) lof
[ 5, 3, 8 ]
但是由于这只是函数应用程序,我们也可以在
($)
上使用节语法。更明确一点> map ($ 4) lof
[ 5, 3, 8 ]
关于haskell - $ 和 () 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24271129/