Haskell - 基本尾递归

时间:2013-02-13 02:14:27

标签: haskell recursion tail-recursion

我有一个带参数的函数

whatIndex ::  (Eq a) => a -> [a] -> Integer

我返回内部[a]的索引,从0开始,如果找不到则返回-1。这就是我写的

module WhatIndex where

whatIndex ::  (Eq a) => a -> [a] -> Integer

whatIndex p [] = -1

whatIndex p (a:as) 
    | p==a = index
    | otherwise = whatIndex p as
    where index = 1+whatIndex p as

显然,我在这里没有正确增加索引。知道为什么这不起作用吗?另外,我无法更改参数。

========================

这是一些基本的输入/输出

whatIndex 3 [] = -1
whatIndex 2 [1,2,3,2,1]=1
whatIndex 1 [1,2,3,2,1]=0
whatIndex 'b' ['a' .. 'z']=1

2 个答案:

答案 0 :(得分:5)

1+whatIndex p as将遍历所有剩余的列表并计算它们,它不会给你索引。只需使用像这样的迭代递归辅助函数......

你可以使用本地功能,也可以使用提升版本,这就是我所拥有的。

whatIndex' ::  (Eq a) => Integer -> a -> [a] -> Integer

whatIndex' _ _ [] = -1

whatIndex' i p (x:xs) 
    | p == x = i
    | otherwise = whatIndex' (i+1) p xs

whatIndex p xs = whatIndex' 0 p xs

main = print $ whatIndex 'a' "bbbbaccc"

这是一个非尾递归版本:

whatIndex p (x:xs)
    | p == x = 0
    | otherwise = 1 + whatIndex p xs

尾递归是指一类递归函数,其中递归函数中的“last”或“final”函数调用是函数本身。这意味着该函数不会在“尾部位置”(函数调用发生的最后一个位置)中调用其他函数(如+)。您可以清楚地看到在whatIndex的第一个版本中调用的最终函数是whatIndex,而在第二个版本中调用的最终函数(调用whatIndex作为参数)是+

http://en.wikipedia.org/wiki/Tail_call

编辑:这是一个与您的规范更紧密对应的版本,虽然它有点复杂且低效。

whatIndex p xs 
    | not (any (==p) xs) = -1
    | otherwise = whatIndex' p xs where
        whatIndex' p (x:xs)
            | p == x = 0
            | otherwise = 1 + whatIndex' p xs

答案 1 :(得分:3)

如果要进行尾递归,请尝试使用accumulator参数:

whatIndex :: (Eq a) => a -> [a] -> Integer
whatIndex =
  let whatIndex' count p [] = -1
      whatIndex' count p (a:as)
        | p==a = count
        | otherwise = whatIndex' (count + 1) p as
  in whatIndex' 0