Haskell语法:drop(n + 1)[] = []是什么意思?

时间:2013-06-26 11:20:54

标签: haskell syntax functional-programming

(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 + 1

更新: 谢谢你指出我正确的术语。我找到了n+k patterns。 由于自2010年以来已删除了n + k个模式,我还在how to enable this pattern上找到了这个问题。

3 个答案:

答案 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 xsn的值将为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

的行为有所不同,因为它是为负数定义的。