1

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

 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返し、残りを返すことを知っています。しかし、私はまだこれの機能を理解できません。これは文字列を受け取り、それを特定の文字からの文字列のリストに分割します。

4

1 に答える 1

3

たぶん、次の形式でより明確になります。

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とは、残りの 'a'`somethingElseを分割することによって後で決定されます。"bc cde". After looking at the first character, it's been determined that whatever the final result is, its first entry starts with残りを決定し続けると、

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 rest@(~(wd : wds))
        | c == delim = "" : rest
        | otherwise  = (c : wd) : wds
于 2012-02-06T10:30:03.547 に答える