我必须通过尾递归获取卡片列表中Card
的数量。我得到了下面的代码:Haskell在列表尾递归中计数元素
amountCard :: Int -> Card -> [Card] -> Int
我试图至今:
amountCard n c [] = n
amountCard n k (x:xs) = if k == x then amountCard (n+1) k xs else amountCard n k xs
难道我用尾递归在这里?
我必须通过尾递归获取卡片列表中Card
的数量。我得到了下面的代码:Haskell在列表尾递归中计数元素
amountCard :: Int -> Card -> [Card] -> Int
我试图至今:
amountCard n c [] = n
amountCard n k (x:xs) = if k == x then amountCard (n+1) k xs else amountCard n k xs
难道我用尾递归在这里?
那么这Wikipedia article说:
[A]尾呼叫是作为一个程序的最后行动 进行子程序调用。如果尾部呼叫可能导致相同子程序 在呼叫链中稍后被再次呼叫,则该子程序被称为 是尾递归,这是递归的特例。尾递归(或尾递归)特别有用,并且在实现中通常易于处理。
(格式化后加)
现在,如果你使用if
- then
- 后else
并没有什么,你知道then
和else
条款的身体将是最后东西“程序”将做。由于在这些then
和else
条款的身体是简单电话(有没有“后处理”像1 + (amountCard n k xs)
),是这的确是尾递归。
我不过说,这是更优雅的使用警卫比if
- then
- else
结构:
amountCard n c [] = n
amountCard n k (x:xs) | k == x = amountCard (n+1) k xs
| otherwise = amountCard n k xs
在Haskell 而且如果一个变量是通常通配符模式使用不重视,如:
amountCard n _ [] = n
amountCard n k (x:xs) | k == x = amountCard (n+1) k xs
| otherwise = amountCard n k xs
而且作为被@chepner注意,您可以通过电子邮件asily你的代码转换为:
amountCard n c [] = n
amountCard n k (x:xs) = amountCard (if k == x then n + 1 else n) k xs
而现在它显然是尾递归,因为第二条的机身仅包含一个调用相同的功能(使用不同的参数)。
请注意,由于'if-then-else'是一个表达式,因此您可以使用它来指定正确的参数而不使用警卫:'amountCard nk(x:xs)= amountCard(if k == x then n + 1 else n)k xs'。 – chepner
@chepner:这确实是一个很好的论点。我用你的节点更新了答案。谢谢。 –
你最好使用*警卫*而不是'if-then-else'。 –