99 Haskell Problems 中的第一个问题是“找到列表的最后一个元素”。我想出了两个解决方案:
解决方案 1(这有效)
myLast :: [a] -> a
myLast = head . reverse
Run Code Online (Sandbox Code Playgroud)
解决方案2(这不起作用)
myLast :: [a] -> a
myLast = head $ reverse
Run Code Online (Sandbox Code Playgroud)
题
head是一个参数1的函数。如果您f $ x习惯将函数应用于某事,则与简单地书写相同f x(或者,如果您喜欢f(x), 或(f)x,所有相同的事情...只是更丑):参数由指定的变量“填充”。因此,当使用's 类型的参数喂食时,结果head $ reverse将只是head给你的任何结果reverse... ...然而这不起作用,因为head需要一个列表但它reverse是一个函数。$本身并不关心这个,而只是处理参数,例如你可以写
Prelude> :t map $ reverse
map $ reverse :: [[a]] -> [[a]]
因为第一个参数map实际上是一个函数。
有了(.)它就不一样了。这关心它右边的参数有什么类型(也必须是一个函数),它不会简单地立即将它提供给左边的函数。相反,f . g产生另一个函数,它执行以下操作:它等待一些参数x,它提供给g,然后将结果提供给f。
现在,如果你写
myLast' = head . reverse
Run Code Online (Sandbox Code Playgroud)
它的意思只是,你定义myLast为这个功能是(.)让你为一体的组成head和reverse。这里没有提到的参数myLast并不重要:[a] -> a只是某种类型,因此您可以定义具有这种类型的变量(如 myLast),通过将它们分配给碰巧具有此类函数类型(如head . reverse)的值。如果需要,您可以使参数显式:
myLast'' x = (head . reverse) x
Run Code Online (Sandbox Code Playgroud)
请注意,括号是必需的,否则它会被解析为head . (reverse x)– 这将不起作用,因为reverse x它不再是一个函数,只是一个结果列表。因此,你不能构成它head; 然而,你可以做的是适用 head于它:
myLast''' x = head $ reverse x
Run Code Online (Sandbox Code Playgroud)
1事实上,Haskell 中的每个函数都只有一个参数……但是我们说“双参数函数”,例如(+) :: Int -> Int -> Int,尽管实际上这是一个单参数函数,返回一个单参数函数,返回一个Int: (+) :: Int -> (Int -> Int)。
| 归档时间: |
|
| 查看次数: |
985 次 |
| 最近记录: |