Haskell 计算列表尾递归中的元素

Haskell count elements in a list tail recursion

我必须通过尾递归获得卡片列表中 Card 的数量。我得到了以下代码:

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] tail call is a subroutine call performed as the final action of a procedure. If a tail call might lead to the same subroutine being called again later in the call chain, the subroutine is said to be tail-recursive, which is a special case of recursion. Tail recursion (or tail-end recursion) is particularly useful, and often easy to handle in implementations.

(已添加格式)

现在如果你使用 if-then-else 之后什么都不用,你知道 thenelse 的正文子句将是 "procedure" 将做的最后一件事。由于在这些 thenelse 子句的正文中是简单的 调用 (有 没有 "post processing" like 1 + (amountCard n k xs)), yes 这确实是尾递归.

然而,我会说使用 guardsif-then-else 结构更优雅:

amountCard n c [] = n
amountCard n k (x:xs) <b>|</b> k == x <b>=</b> amountCard (n+1) k xs
                      <b>| otherwise =</b> amountCard n k xs

此外,在 Haskell 中,如果变量不重要,通常会使用 通配符模式 ,例如:

amountCard n <b>_</b> [] = n
amountCard n k (x:xs) | k == x = amountCard (n+1) k xs
                      | otherwise = amountCard n k xs

此外,如 所述,您可以轻松地将代码转换为:

amountCard n c [] = n
amountCard n k (x:xs) = amountCard <b>(if k == x then n + 1 else n)</b> k xs

现在显然是尾递归,因为第二个子句的主体仅包含对同一函数的一次调用(具有不同的参数)。