2

私はHaskellを学んでおり、パターンマッチングがどのように機能するかを理解しようとしています. そうすることで、私は簡単なnth関数を書きました。

nth' :: Integer -> [a] -> a
nth' n [] = error "Index out of bound"
nth' n (x:xs) = if n == 0 then x else nth' (n - 1) xs

この最初の実装は期待どおりに動作するようです。

-- nth' 25 ['a'..'z']
-- 'z'
-- nth' 26 ['a'..'z']
-- *** Exception: Index out of bound

ただし、if ステートメントをパターン マッチングに置き換えてリファクタリングすると、明らかにすべきではない "Index out of bound" 例外が発生します。

nth' :: Integer -> [a] -> a
nth' _ [] = error "Index out of bound"
nth' 0 (x:[]) = x
nth' n (_:xs) = nth' (n - 1) xs

-- nth' 2 ['a'..'z']
-- *** Exception: Index out of bound

私は何を間違っていますか?

4

3 に答える 3

13

パターンx:[]は、要素を 1 つだけ含むリストに一致します。したがって、nth' 0 (x:[])ケースは、最初の引数が 0 で、2 番目の引数が 1 要素のリストである場合にのみ実行されます。2 番目の引数が複数の引数を持つリストの場合、最後のケースに入ります。

2 番目のケースを に変更する必要がありますnth' 0 (x:_) = x。これにより、リスト内の要素の数に関係なく (少なくとも 1 つであれば) 一致します。

于 2013-03-09T16:25:19.850 に答える
6

問題のある条項:

nth' 0 (x:[]) = x

1 要素リストのみに一致します。次のように変更してみてください。

nth' 0 (x:_) = x
于 2013-03-09T16:26:03.933 に答える
1

試す:

    nth' :: Integer -> [a] -> a
    nth' _ [] = error "Index out of bound"
    -- nth' 0 (x:[]) = x -- matches one element list x:[] = [x]
    nth' 0 (x:_) = x     -- matches first element and everything (not just empty list)
    nth' n (_:xs) = nth' (n - 1) xs
于 2013-03-09T16:35:30.400 に答える