実際に挙げていただいたコードを実行したところ、実際には止まらないのではなく、エラーが発生して止まってしまうようです:
haskell
1> cat test.hs
2test::[String]->String
3test (x:xs)
4 |x==[]=""
5 |x=="g"="h"++test xs
6 |otherwise =x++test xs
7
8main=do
9 let hoge=test ["h","o","g","e"]
10 print(hoge)
bash
1> stack exec runghc test.hs
2test.hs: test.hs:(2,1)-(5,23): Non-exhaustive patterns in function test
発生しているエラー「Non-exhaustive patterns in function test」は、件のtest
関数においてパターンマッチに漏れがある、ということを表すエラーです。盛れているケースを実行した場合に、問題のようなエラーが発生します。
事実、test
関数はガード節を使ってx
、つまり引数であるリストにおける先頭の要素である文字列に対して漏れのないコードを書いているものの、引数であるリスト全体、つまり (x:xs)
に対するコードに抜け漏れがあります。具体的には、[]
、つまり空のリストです。test
関数は、(x:xs)
というパターンで引数であるリスト全体が空でない場合を想定してはいるものの、空である場合は想定できていません。なので、直すとしたら次のように空の場合のコードを書いてあげましょう:
haskell
1test::[String]->String
2test (x:xs)
3 |x==[]=""
4 |x=="g"="h"++test xs
5 |otherwise =x++test xs
6test [] = -- ここから先は自分で考えてください!
今ひとつnk598xvさんの実現したい仕様が読み取れないので、詳細なコードは書きません。
なお、本筋からそれますが、
x==[]=""を x==""=""にしても止まりませんでした。
という質問文からして、この関数が「文字列のリスト」を扱っているにも関わらず、単なる文字列と混同してしまっているようです。
該当の箇所においてx
はString
型、つまり文字列であり、Haskellではそのまま文字のリスト([Char]
)でもあります。なので、その箇所では空の文字列""
と[]
は完全に同じものとして扱われてしまうので、x==[]=""
をx==""=""
に変えても結果は何も変わりません。本件のように文字列のリスト、言い換えると文字のリストのリストを扱う場合は、リストが入れ子になっているので、
- 各要素(
test
関数でいうところのx
)、における各要素(つまり文字)に対してどう繰り返し処理を行う(再帰呼び出しを行う)のか、という点と、
- 第一引数として受け取っている文字列のリストにおける各要素(つまり文字列)に対してどう繰り返し処理を行うのか、
以上の2段階に分けて考えないといけないので、ご注意ください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/07/25 03:15