0

パラメータを持つ関数があります

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

ここで、0 から始まる [a] 内の a のインデックスを返します。見つからない場合は -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

末尾再帰とは、再帰関数の「最後」または「最終」関数呼び出しが関数自体に対するものである、再帰関数のクラスを指します。つまり、関数が+「テール位置」(関数呼び出しが行われる最後の場所) で他の関数 ( など) を呼び出していないことを意味します。whatIndexの最初のバージョンで呼び出される最終関数は であるwhatIndexのに対し、2 番目のバージョン (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

末尾再帰が必要な場合は、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
于 2013-02-13T02:25:17.823 に答える