web-dev-qa-db-ja.com

機能の非網羅的なパターン

このコードに問題があります。文字列内の同じ文字の最も長い部分文字列を数える必要がありますが、エラーがあります。

*** Exception: test.hs:(15,0)-(21,17): 
Non-exhaustive patterns in function countLongest'

私はそれが間違ったタイプの問題であることを知っていますが、どこにエラーがあるのか​​、それを見つけたりデバッグする方法はわかりません

countLongest :: (Eq a) => [a] -> Int
countLongest' :: (Eq a) => Int -> Int -> [a] -> Int

countLongest a = countLongest' 0 0 a
countLongest' n max (y:x:ys)
        | y == x = countLongest' (n+1) max (x:ys)
        | n > max = countLongest' 0 (n) (x:ys)
        | otherwise = countLongest' 0 (max) (x:ys)
countLongest' n max []
        | n > max = n
        | otherwise = max
25
kaz

1つの要素のリストがある場合を見逃しているようです。

countLongest' n max (y:ys)
    | ... etc. ...
    | otherwise = ....

ここにあなたのような不自然な例があります:

f [] = 3         -- matches an empty list
f (a:b:bs) = 4   -- matches a list with at least two elements

例:

Prelude> :load myfile.hs 
[1 of 1] Compiling Main             ( myfile.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [3]
*** Exception: myfile.hs:(3,0)-(4,13): Non-exhaustive patterns in function f

*Main> f []
3
*Main> f [1,2,3,4,5]
4
*Main> 

そのため、リストの要素が0と2の場合は成功しますが、要素が1つしかない場合は失敗します。


この動作はリストに固有ではないことに注意してください。 Maybeを使用した例を次に示します。

g :: Maybe x -> x
g (Just x) = x

例:

*Main> g (Just 4)
4
*Main> g Nothing 
*** Exception: myfile.hs:6:0-13: Non-exhaustive patterns in function g

これは、MaybeJust <something>、およびNothingの2つのコンストラクターがあるために発生しました。 Nothingのケースは提供していなかったため、gに渡しても機能しませんでした。


コンパイラから少し助けを得るための情報について、 この質問 とその回答を確認してください。私は最初の答えのアドバイスに従いました、そして私の例をロードしたとき、これは何が起こったかです:

Prompt$ ghci -fwarn-incomplete-patterns

Prelude> :load myfile.hs 
[1 of 1] Compiling Main             ( myfile.hs, interpreted )

myfile.hs:3:0:
    Warning: Pattern match(es) are non-exhaustive
             In the definition of `f': Patterns not matched: [_]

myfile.hs:6:0:
    Warning: Pattern match(es) are non-exhaustive
             In the definition of `g': Patterns not matched: Nothing
Ok, modules loaded: Main.

涼しい!コンパイラーはかなりスマートです!

41
Matt Fenwick

問題は、再帰に1つの要素が残っている場合に一致する必要があることです。次に例を示します。

countLongest' n max (y:ys)

2つ以上の要素が残っている場合は最初の要素が一致し、要素が残っていない場合は最後の要素が一致するためです。

4
glindste