0

我有一个有参数的函数

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
4

2 回答 2

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

尾递归是指一类递归函数,其中递归函数中的“最后”或“最终”函数调用是针对函数本身的。所以这意味着该函数没有+在“尾部位置”(发生函数调用的最后一个位置)调用其他函数(如 )。您可以清楚地看到,在第一个版本中调用的最终函数whatIndexwhatIndex,而在第二个版本中调用的最终函数(将调用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
于 2013-02-13T02:25:34.400 回答
3

如果您想要尾递归,请尝试使用累加器参数:

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
于 2013-02-13T02:25:17.823 回答