我只是想知道,对于递归示例:
squaresRec :: [Double] -> [Double]
squaresRec [] = []
squaresRec (x:xs) = x*x : squaresRec xs
为什么在递归的情况下,没有括号?难道不应该这样:
squaresRec :: [Double] -> [Double]
squaresRec [] = []
squaresRec [x:xs] = x*x : squaresRec xs
我知道这不行。但只是想知道背后的解释。
答案 0 :(得分:5)
[]
匹配空列表。
[1]
匹配仅包含一个元素的列表,且该列表必须是等于1的数字。请注意,[1]
实际上是(1:[])
的语法糖,即它真正匹配的是:以数字1
开头的列表,后跟一个空的列表...这只是一种复杂的说法“包含单个元素1
”的列表。
(x:xs)
匹配以x
开头的列表,后跟xs
(可能包含任意数量的元素,可能为零)。即此模式匹配任何列表至少一个元素。
[x:xs]
再次匹配包含完全一个元素的列表,该元素应与模式(x:xs)
匹配。 (即使是类型也没有意义,因为你的列表包含Double
- 数字,而不是列表。)
答案 1 :(得分:3)
我遇到了同样的问题因为我来自Erlang。
要理解的是,我们在Erlang中的[head | tail]模式实际上是由Haskell中的cons
函数翻译的,它是:
运算符。括号只是用于隔离函数参数,如(3 + 4)那样。
我知道很有可能会问“为什么会这样?”并且它在视觉上更有意义,但:
是我们如何构建(并在模式匹配时分离)链接列表的头部和尾部。