トップページへ

パターンマッチングについて

Access Count : 10759

Copyright © 2020 TAKEHANA TADASHI
著作日時: 2020.02.28.金. 22:56:00 著作者、竹花 忠
パターンマッチングについて:
 パターンマッチングとは、右辺のデーターを受け取る形式を指し示す左辺の記述、の事を指して言う。
 パターンマッチングとは、あるデータが、どんな形式であるかを明記して、その形式でそのあるデータを受け取る。
 その際、構成要素の複合した形式を明記して、当該データを受け取ることで、複合的なデータを構成する各構成要素が、明記した各構成要素名に束縛される。
 それによって、複合的なデータの各構成要素が直接、各構成要素の名前によって取り扱えることが実現する。
 例、
(a, b) = (1, 2)
によって、複合的なデータである(1, 2)というタプルデータが、その構成要素である第一要素と第2要素をそれぞれ、aとbという名前によって直接、取り扱える。
sum = a + 19とすれば、aは1なので20がsumに得られる。mul = b * 61とすれば、bは2なので122がmulに得られる。というように、複合的データの各構成要素がそれぞれ別々の変数名で取り扱えることになる。
 変数1個でパターンマッチングすれば、その変数が、マッチングされたデータの全容を保持することになる。
 例、
c = (1, 2)
によって、変数cは、(1, 2)というタプルデータの全容を保持することになる。
kei = c + (2, 3)とすれば、cは(2, 3)なので、(3, 5)がkeiに得られる。

 あるいはまた、パターンマッチングとは、関数の定義の記述において、関数を呼び出している時の各引数がどんな形式になっているかを表記して、その形式での関数呼び出しであった時のその関数の定義を記述するスペースを確保する、そういうことのためのプログラムの記述パーツでもある。
 例、
bunri :: String -> String -> Int -> [String]
bunri [] _ _ = []

bunri list@('\n':xs) [] sepcnt =
 let
  (h, t) = break (/= '\n') list
 in
  bunri t [] sepcnt

bunri list [] sepcnt =
 let
  (h, t) = break (== '\n') list
 in
  bunri t h sepcnt

bunri list@('\n':xs) buf sepcnt =
 let
  (h, t) = break (/= '\n') list
  lc = length h
 in
  if lc >= sepcnt then (buf ++ h) : bunri t [] sepcnt
          else bunri t (buf ++ h) sepcnt

bunri list buf sepcnt =
 let
  (h, t) break (== '\n') list
 in
  bunri t (buf ++ h) sepcnt

 この、第1引数が[]である記述は、その引数が[]であった場合に一致する。ただし、第2、第3引数の位置は、_なので、その値は何であってもいい。(パターンマッチング)
 その時には、その右の=以降の定義に進んで、そして、この関数の定義群を抜け出す。

 list@('\n':xs)が表していることは、下記の通りである。
 第1引数のリストの先頭要素が'\n'で、その後続のリストをxsで受け取る。(バターンマッチング)
 なおかつ、第2引数の位置は[]なので、第2引数の値が[]だったら一致する。(バターンマッチング)
 なおかつ、第3引数の値は、sepcntで受け取る。(バターンマッチング)
 それらに一致できたら、その右の=以降の定義へ進んで、そして、この関数の定義群を抜け出す。

 第1引数の位置のlistが表していることは、下記の通りである。
 第1引数のリストをlistで受け取る。(パターンマッチング)
 なおかつ、第2引数の位置は[]なので、第2引数の値が[]だったら一致する。(バターンマッチング)
 なおかつ、第3引数の値は、sepcntで受け取る。(バターンマッチング)
 それらに一致できたら、その右の=以降の定義へ進んで、そして、この関数の定義群を抜け出す。

 list@('\n':xs)が表していることは、下記の通りである。
 第1引数のリストの先頭要素が'\n'で、その後続のリストをxsで受け取る。(バターンマッチング)
 なおかつ、第2引数の値は位置はbufで受け取る。(バターンマッチング)
 なおかつ、第3引数の値は、sepcntで受け取る。(バターンマッチング)
 それらに一致できたら、その右の=以降の定義へ進んで、そして、この関数の定義群を抜け出す。

 第1引数の位置のlistが表していることは、下記の通りである。
 第1引数のリストをlistで受け取る。(パターンマッチング)
 なおかつ、第2引数の値をbufで受け取る。(バターンマッチング)
 なおかつ、第3引数の値は、sepcntで受け取る。(バターンマッチング)
 それらに一致できたら、その右の=以降の定義へ進んで、そして、この関数の定義群を抜け出す。


 後者の例は、第1引数で渡したコンテンツを、第3引数で指定した個数、以上の連続改行の位置で分割する。そして、その分割されたブロックコンテンツのリストを返す。
 それが、bunri関数である。ただし、コンテンツの先頭の連続改行は、無視する・捨てる。
 以上の仕様の関数として、上記のbunri関数は記述されている。
 各関数の定義のロジックを下記に順次述べておく。

 第1引数で渡されてきたコンテンツが空リストだった時は、空リストを返す。

 第1引数のコンテンツが改行から開始されていて、その時、ブロックコンテンツの溜め込み領域である第2引数が空リストであったら、つまりまだ空であった時。その時には、改行である限りにわたってhに格納し、それ以降をtに格納する。
 そして、hは無視して、第1引数のコンテンツを後続のデータtにして再度、bunri関数を実行する。

 第1引数のコンテンツが改行以外から開始されていて、その時、ブロックコンテンツの溜め込み領域である第2引数が空リストであったら、つまり、まだ空であった時。その時には、改行でない限りにわたってhに格納し、それ以降をtに格納する。
 そして、hは第2引数のブロックコンテンツの溜め込み領域に設定。第1引数には後続のデータtを設定して、再度、bunri関数を実行する。

 第1引数のコンテンツが改行から開始されていて、その時、ブロックコンテンツの溜め込み領域である第2引数にはすでにデータが溜め込まれていた時。その時には、改行である限りにわたってhに格納し、それ以降のデータをtに格納する。
 hの文字数をlcに取得する。つまり、連続改行個数をlcに取得。
 連続改行個数が、第3引数sepcntに設定されている数値以上の時、第2引数のブロックコンテンツの溜め込み領域のbufに読み込みだ連続改行データhを連結して、それを結果リストに登録。そして、第2引数のブロックコンテンツの溜め込み領域を空リストにクリアして、第1引数は後続のデータに更新して、再度、bunri関数を実行。
 連続改行個数が第3引数sepcntに設定されている数値未満だった時、第2引数のブロックコンテンツの溜め込み領域bufに読み込んだ連続改行データhを連結して、それを再度第2引数に設定。そして、第1引数に後続のデータtを設定して、再度、bunri関数を実行。

 第1引数のコンテンツが改行以外から開始されていて、その時、ブロックコンテンツの溜め込み領域にすでにデータが溜め込まれていた時。改行でない限りにわたってhに格納し、それ以降のデータをtに格納する。
 そして、hを、第2引数のブロックコンテンツの溜め込み領域bufに連結して、第2引数に再設定。第1引数には後続のデータを設定して、再度、bunri関数を実行。

 なお、このbunri関数の実行においては、第3引数には、常に、sepcntを設定し続ける。
 sepcntは、コンテンツを連続改行何個以上で切り分けるかを指定した数値である。
 連続改行3個以上でコンテンツを切り分けたいなら、3を指定しておく。