1. ホーム
  2. haskell

[解決済み] 機能における非網羅的なパターン【重複あり

2022-02-08 14:38:31

質問事項

このコードでは、文字列中の同じ文字の最長の部分文字列を数えるはずなのですが、エラーが発生するんです。

*** 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

解決方法は?

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

のコンストラクタが2つあるため、このような現象が起きました。 Maybe , Just <something>Nothing . のケースは用意しませんでした。 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.

かっこいい! コンパイラはかなり賢い!