2010-05-06 71 views
6

我的工作我的方式,通过格雷厄姆赫顿的哈斯克尔的书,并在他的递归章中,他经常上“N + 1”的格局,比赛,如:下面为什么Haskell“'n + 1'和'n'”中的递归习惯用法不是''n'和'n-1'“?

myReplicate1 0 _ = [] 
myReplicate1 (n+1) x = x : myReplicate1 n x 

为什么,而不是哪(1)似乎是在理解方面功能相同;(2)更直观发生的事情与递归:

myReplicate2 0 _ = [] 
myReplicate2 n x = x : myReplicate2 (n-1) x 

有我丢失的东西吗?或者这只是一个风格问题?

回答

11

这些都是n + k模式(应该避免!)在第一个函数中。两个函数都做同样的事情,除了n + k不匹配负数。然而,推荐使用后者,,如果您不想使用负号,则可以采用后者,因为n + k模式被视为removed anyways

所以不,你什么也没有失去,这确实是一个风格问题,但我很少在野外看到n + k模式。

+1

换句话说,这是一个风格问题,第一种风格已被弃用。:) – 2010-05-06 21:39:38

+0

是的,只是编辑它:) – LukeN 2010-05-06 21:40:40

+2

他们实际上是不一样的。 n + k模式不匹配负数。 – sepp2k 2010-05-06 21:44:01

2

当n> = 0时,n + k模式只匹配。因此,在您的myReplicate1中,n + 1模式将仅匹配正数,而负n将导致非穷举模式例外。在myReplicate2中,负n会创建一个无限列表。

换句话说,如果您不希望图案与负数匹配,您可以使用n + k图案,但使用防护罩会更清晰。

-4
myReplicate n x = take n (repeat x) 

完成并完成。 :D

+6

是的,这是真正有用的... – Joren 2010-05-06 21:46:00

3

N + K模式也有不同严格的含义。

例如:

f (n+1) = Just n 
g n = Just (n-1) 

f是严格上的第一个参数,g不。这与n + k模式没什么特别之处,但适用于所有模式。

5

我认为这背后的想法是这样的:我们可以定义一个(慢)一种自然数类型是这样的:

data Natural = Zero | S Integer 

所以0 == Zero1 == S Zero等。

执行此操作时,会更自然使用模式匹配这样的:

myReplicate1 Zero _ = [] 
myReplicate1 (S n) x = x : myReplicate1 n x 

我认为(这只是一个猜测),其背后n+1模式的想法是,它像一个快速的版本是什么我刚才描述。所以n+1被认为是模式S n。所以如果你这样想,n+1模式看起来很自然。

这也说明了为什么我们有条件是n>=0。我们只能用Natural代表n>=0

相关问题