テキストスプリッタの背後にあるHaskellのパターンマッチングの概念

このコードスニペットの背後にあるパターンマッチングの概念を知りたい:

 split :: String -> Char -> [String]
 split [] delim = [""]
 split (c:cs) delim
     | c == delim = "" : rest
     | otherwise = (c : head rest) : tail rest
       where
         rest = split cs delim

head はリストの最初の要素を返し、 tail は残りを返します。しかし、私はまだこの機能を理解できません。これは文字列を受け取り、与えられた文字から文字列のリストに分割します。

1

1 答え

たぶんそれは次のような形ではっきりしています:

split [] delim = [""]    -- a list containing only an empty String
split (c:cs) delim = let (firstWord:moreWords) = split cs delim
                     in if c == delim
                           then "" : firstWord : moreWords
                           else (c:firstWord) : moreWords

この関数は、各文字を区切り文字と比較して入力文字列を走査します。現在の文字が区切り文字でない場合は、文字列の残りの部分を分割した結果の最初の単語の前にタックが付けられます(空の場合もあります)。区切り文字の場合は、空の文字列が先頭に追加されます残りの部分を分割した結果の

たとえば、 split "abc cde" '' の評価は以下のように進行します。

split "abc cde" ' '
    ~> 'a' == ' ' ? No, next guard
    ~> ('a' : something) : somethingElse

something somethingElse は、残りの "bc cde"を分割して後で決定します。最初の文字を見ると、最終結果が何であれ、最初のエントリは 'a'で始まります。残りを決定するために進むと、

split "bc cde" ' '
    ~> ('b' : something1) : somethingElse1
       where (something1 : somethingElse1) = split "c cde" ' '

したがって、結果の最初のエントリの最初の2文字が分かりました。次のステップから something1 'c' で始まると判断されます。最後に、デリミタに到達します。これは、結果の最初の要素が後の再帰呼び出しを参照せずに決定され、残った結果のみが再帰で見つかるままである場合です。

アルゴリズムを定式化するもう一つの方法は、(おかげさまで@ dave4420の提案です)

split input delim = foldr combine [""] input
  where
    combine c [email protected](~(wd : wds))
        | c == delim = "" : rest
        | otherwise  = (c : wd) : wds
3
追加された
@Gihan split "abc cde" '' ["abc"、 "cde"] を生成します。あなたの次の質問を理解しているかどうかは分かりませんが、もしそうなら<head> head split 実際にはString です。
追加された 著者 Daniel Fischer,
私は自分の答えを広げました。おそらくそれで十分に明確になります(そうでなければ、もう一度質問してください)。
追加された 著者 Daniel Fischer,
わかりません。各(有限と完全に定義された)リストは、空のリスト [] で終わります。区切り文字(または入力の終わり)に達するたびに、空のリスト( Char の空の String )が挿入されて、1つのチャンクの終わりをマークします。
追加された 著者 Daniel Fischer,
したがって、空の文字列をfromに追加すると、文字列が分割されます。つまり、文字列が文字列のリストに分割される方法です。 ?区切り文字が見つかった場合、それは何を返しますか? exapmpleのように、 "abc cde"という文字列をスペースから区切らなければならないと言っています。そして、 "それは" "、" cde "または" cde "を返します。 ..?
追加された 著者 Gihan,
ええ、それは本当です。次の質問については、このように。分割したい文字列は "abc cde" です。これは7文字です。これには7回の再帰段階があります。最終段階から開始されます。 "E" を返します。 6th recurは "EF" のように E:F:Null を返します。 "DEF" のように D:E:F を返します。 4階にスペースが来る。次に、 "": "DEF" になります。そこで、これが質問の出番です。そこから( ""、 "DEF")または "DEF" ...として返されますか?
追加された 著者 Gihan,
3番目のレベルで( ""、 "DEF")であれば、 C: "": "DEF" "、" "、" DEF "
追加された 著者 Gihan,
ええ、それは仲間を得た。私は後ろ向きに考えていた。助けてくれてありがとう。心から感謝する。もう一つだけ、空の文字列を使うのはなぜ? "それの専門は何ですか?
追加された 著者 Gihan,
それはすごく行く....クリスタルとしてクリア...!再度、感謝します
追加された 著者 Gihan,