(n+1)
是什么意思?我知道它们都是递归的Haskell函数,并且正在使用模式匹配。
我不明白它将如何匹配factorial (n+1)
以及(n+1)
的RHS上的factorial =
。
使用drop
函数为什么drop 0 xs = xs
?那么drop (n+1) [] = []
呢?
--Example 1
factorial 0 = 1
factorial (n+1) = (n+1) * factorial n
--Example 2
drop :: Int -> [a] -> [a]
drop 0 xs = xs
drop (n+1) [] = []
drop (n+1) (_:xs) = drop n xs
顺便说一句,我在编译时遇到错误。
更新: 谢谢你指出我正确的术语。我找到了n+k patterns。 由于自2010年以来已删除了n + k个模式,我还在how to enable this pattern上找到了这个问题。
答案 0 :(得分:7)
这些是NPlusKPatterns
,已于2010年从语言中删除,现在只能使用上述语言扩展名。
n + k
- 模式
drop (n+1) [] = []
如果参数值为n
,则将>= 1
绑定到参数值减1。该模式与参数<= 0
不匹配。
所以,如果
drop :: Int -> [a] -> [a]
drop 0 xs = xs
drop (n+1) [] = []
drop (n+1) (_:xs) = drop n xs
使用负Int
参数调用,如
drop (-2) "foo"
没有模式匹配,你得到一个例外。
通常,如果你定义(对于一个愚蠢的例子)
foo :: Int -> Int
foo (n+5) = 3*n
foo (n+2) = n
foo (n+1) = 2*n
如果您拨打foo 7
,则第一个模式匹配,n
将绑定到2
,因此foo 7 = 6
。如果您致电foo 3
,则第一个模式不匹配(3-5 = -2 < 0
),但第二个模式不匹配,并将n
绑定到3-2 = 1
,因此foo 3 = 1
。如果您拨打foo 1
,前两个模式都不匹配,但最后一个模式匹配,然后n
绑定到1 - 1 = 0
,因此foo 1 = 0
。使用参数foo
调用< 1
会引发异常。
使用drop函数为什么
drop 0 xs = xs
?那么drop (n+1) [] = []
呢?
好吧,drop 0
会从列表前面删除0个元素,因此它根本不会更改列表参数。并且您不能从空列表中删除元素,因此除了引发错误之外,drop (n+1) [] = []
是唯一可以执行的操作。
答案 1 :(得分:6)
这是一种所谓的n+k
模式。模式(n+1)
匹配任何正整数,并给出n
该整数的值减1。因此,如果您致电drop 1 xs
,n
的值将为0。
为什么是
drop 0 xs = xs
因为如果从列表中删除0个元素,最终会得到相同的列表。
那么
drop (n+1) [] = []
呢?
这就是说,如果从空列表中删除任意数量的项目,最终会得到一个仍为空的列表。除了失败的错误信息之外,在这种情况下,这确实是唯一明智的做法。
答案 2 :(得分:3)
您提供的代码使用名为NPlusKPatterns
的功能,该功能不再是标准haskell的一部分(不在haskell2010
标准中),但可以通过放置线来“导入”它
{-# LANGUAGE NPlusKPatterns #-}
位于源文件的顶部。
让我们看一下如何使用它的例子:
myFunction 0 = 0
myFunction (n+1) = n
这个功能有点傻。如果输入为0
,则结果为0
。对于正输入数m
,结果为m - 1
,或换句话说,对于正输入数n+1
,结果为n
。由于(n+1)
模式与负数不匹配,因此未对负数进行定义。
现在我可以说我将我的功能改为
myFunction 0 = 0
myFunction (n+1) = (n+1)
现在左侧做了一些魔术。它声明了一个变量n
,它是一个减去输入的变量。另一方面,右侧使用(+)
运算符向其添加一个。
关于drop
功能的问题。 drop 0 xs = xs
表示从列表中删除0
元素不会更改列表。 drop (n+1) [] = []
只是从空列表中删除任何正数的元素就是空列表。
drop
报告中haskell2010
的定义是:
drop n xs | n <= 0 = xs
drop _ [] = []
drop n (_:xs) = drop (n-1) xs
的行为有所不同,因为它是为负数定义的。