トップページへ

再帰呼び出し関数の基本プログラム

Access Count : 1293

Copyright © 2021 TAKEHANA TADASHI
{--
Created Date : 2021.05.31.mon. 20:12:00
Update : 2021:06.02.wed. 13:48:00

再帰呼び出し関数の基本プログラム:


SsaikiKihon.hs

摘要:
 リストデーター全体にわたっての処理結果は、その先頭要素に対しての処理結果とその残余のリストに対しての処理結果から構成される。
 このことに間違いはない。
 そして、このように分割して再構成して表現すると、残余に対しての処理結果についても、それに対して同様に、その先頭要素に対しての処理結果とその残余のリストに対しての処理結果によって表現できる。
 そしてまた、その残余のリストに対しての処理結果についても、同様に、その先頭要素に対しての処理結果とその残余のリストに対しての処理結果によって表現できる。
 そしてまた、その残余のリストに対しての処理結果についても、同様に、・・・。
               ・
               ・
               ・
 リストデーター全体にわたっての処理結果を、その先頭要素に対しての処理結果とその残余のリストに対しての処理結果で表現することで、たったそれだけの表現だけで、自動的に上述したように、その表現の繰り返し適用が発生するので・その表現の順次適用が発生するので・その表現の連鎖適用が発生するので、先頭のデーターから順に、そのリストの各要素の処理結果が求められて、それがリスト構築子なりプラス演算記号なりで連結された、リストの全要素が処理された結果値となる。
 この記述形式が、Haskell言語におけるリストの全データーを処理する場合の定義の記述の仕方の定法のひとつである。
 なお、この、先頭要素に対しての処理結果とその残余のリストに対しての処理結果とに、分割して再構成する表現では、終端においては、空リストが出現することになる。空リストは、先頭要素とその残余のリストに分割して表現できない。
 また、空リストに至った時には、リストの全要素についての処理は終了していて、それ以上に処理を続行する必要もない。
 であるから、残余のリストに対しての処理を求める記述が、空リストを残余のリストとしての処理になった時には、そこで分割と再構成の連鎖を停止させる適切な処理に置き換わるように定義しておくことが必要である。
 先頭要素の処理結果とその残余のリストに対しての処理結果とを、リスト構築子で再構成していた時には、空リストに対しての処理の実行になった時に、空リストに置き換える。あるいはまた、プラス演算子やマイナス演算子で再構成していたときには、空リストに対しての処理になった時、0に置き換える。またあるいは、掛ける演算子や割る演算子で再構成していた時には、空リストに対しての処理りになった時、1に置き換える。
 以上のように、終端データーに達した時の、処理・表現、と、それ以外の時の、先頭要素に対しての処理結果とその残余のリストに対しての処理結果とに、分割して再構成する表現、とによる定義のセットで、関数を記述する。
 これが、リストの全要素に対して処理を行う場合の再帰呼び出し関数の記述、の仕方の基本形である。

 下記のbaiHiku1の定義において、baiHiku1 [1,2,3,4]が与えられたら、これは自動的に、(1 * 2 - 1) : baiHiku1 [2,3,4]に置き換わる。
 そしてそれはさらに、自動的に、(1 * 2 - 1) : (2 * 2 - 1) : baiHiku1 [3,4]に置き換わる。
 そしてさらに自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : baiHiku1 [4]に置き換わる。
 さらに自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : baiHiku1 []に置き換わる。
 そして自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : []に置き換わる。
 これは、1 : 3 : 5 : 7 : []なので、結局、[1,3,5,7]に置き換わって終了する。

 下記のbaiHiku1Waの定義において、baiHiku1Wa [1,2,3,4]が与えられたら、これは、自動的に、(1 * 2 - 1) + baiHiku1Wa [2,3,4]に置き換わる。
 そしてそれはさらに自動的に、(1 * 2 - 1) + (2 * 2 - 1) + baiHiku1Wa [3,4]に置き換わる。
 そしてさらに自動的に、(1 * 2 - 1) + (2 * 2 - 1) + (3 * 2 - 1) + baiHiku1Wa [4]に置き換わる。
 さらに自動的に、(1 * 2 - 1) + (2 * 2 - 1) + (3 * 2 - 1) + (4 * 2 - 1) + baiHiku1Wa []に置き換わる。
 そして自動的に、(1 * 2 - 1) + (2 * 2 - 1) + (3 * 2 - 1) + (4 * 2 - 1) + 0に置き換わる。
 これは、1 + 3 + 5 + 7 + 0なので、結局、16に置き換わって終了する。

 下記のbaiHiku1Sekiの定義において、baiHiku1Seki [1,2,3,4]が与えられたら、これは、自動的に、(1 * 2 - 1) * baiHiku1Seki [2,3,4]に置き換わる。
 そしてそれはさらに自動的に、(1 * 2 - 1) * (2 * 2 - 1) * baiHiku1Seki [3,4]に置き換わる。
 そしてさらに自動的に、(1 * 2 - 1) * (2 * 2 - 1) * (3 * 2 - 1) * baiHiku1Seki [4]に置き換わる。
 さらに自動的に、(1 * 2 - 1) * (2 * 2 - 1) * (3 * 2 - 1) * (4 * 2 - 1) * baiHiku1Seki []に置き換わる。
 そして自動的に、(1 * 2 - 1) * (2 * 2 - 1) * (3 * 2 - 1) * (4 * 2 - 1) * 1に置き換わる。
 これは、1 * 3 * 5 * 7 * 1なので、結局、105に置き換わって終了する。

 ちなみに、リストデーター全体にわたっての処理結果は、その先頭要素とその次の要素に対しての処理結果とその残余のリストに対しての処理結果から構成される。
 このことにも間違いはない。
 そして、このように分割して再構成して表現すると、残余に対しての処理結果についても、それに対して同様に、その先頭要素とその次の要素に対しての処理結果とその残余のリストに対しての処理結果によって表現できる。
 そしてまた、その残余のリストに対しての処理結果についても、同様に、その先頭要素とその次の要素に対しての処理結果とその残余のリストに対しての処理結果によって表現できる。
 そしてまた、その残余のリストに対しての処理結果についても、同様に、・・・。
               ・
               ・
               ・
 なお、この、先頭要素とその次の要素に対しての処理結果とその残余のリストに対しての処理結果とに、分割して再構成する表現では、終端においては、空リストが出現することになるか先頭の要素と空リストのセットが出現することになるかのどちらかである。
 いずれにしても、空リストの手前のデーターまでで処理を終了させたいので、空リストで関数呼び出しをした時には、空リストだけを返す。データーと空リストのセットで関数呼び出しをした時には、データーに対しては処理を行った結果を返し、空リストに対しては空リストを返す。
 そうしておけば、2通りの終端のいずれにも対応できる。
 なので、このように記述しても、それはそれで正常に動作する。

 下記のbaiHiku1accTwoの定義において、baiHikuacc1Two [1,2,3,4]が与えられたら、これは自動的に、(1 * 2 - 1) : (2 * 2 - 1) : baiHiku1accTwo [3,4]に置き換わる。
 そしてさらに自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : baiHiku1accTwo []に置き換わる。
 そして自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : []に置き換わる。
 これは、1 : 3 : 5 : 7 : []なので、結局、[1,3,5,7]に置き換わって終了する。

 また、下記のbaiHiku1accTwoの定義において、baiHikuacc1Two [1,2,3,4,5]が与えられたら、これは自動的に、(1 * 2 - 1) : (2 * 2 - 1) : baiHiku1accTwo [3,4,5]に置き換わる。
 そしてさらに自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : baiHiku1accTwo [5]に置き換わる。
 そして自動的に、(1 * 2 - 1) : (2 * 2 - 1) : (3 * 2 - 1) : (4 * 2 - 1) : (5 * 2 - 1) : []に置き換わる。
 これは、1 : 3 : 5 : 7 : 9: []なので、結局、[1,3,5,7,9]に置き換わって終了する。

--}

import Prelude

main = do
 let
   dat1 = baiHiku1 [1,2,3,4] -- リストの全データーをbaiHiku1で処理した時の値。
   dat2 = baiHiku1Wa [1,2,3,4] -- リストの全データーをbaiHiku1Waで処理した時の値。
   dat3 = baiHiku1Seki [1,2,3,4] -- リストの全データーをbaiHiku1Sekiで処理した時の値。
 print dat1
 print dat2
 print dat3

 let
   data1 = baiHiku1accTwo [1,2,3,4] -- リストの全データーをbaiHiku1accTwoで処理した時の値。
   data2 = baiHiku1accTwo [1,2,3,4,5] -- リストの全データーをbaiHiku1accTwoで処理した時の値。
 print data1
 print data2



baiHiku1 [] = []
baiHiku1 (x:xs) = (x * 2 - 1) : baiHiku1 xs

--baiHiku1 [1,2,3,4]の時、[1,3,5,7]を返す。


baiHiku1Wa [] = 0
baiHiku1Wa (x:xs) = (x * 2 - 1) + baiHiku1Wa xs

--baiHiku1Wa [1,2,3,4]時、16を返す。


baiHiku1Seki [] = 1
baiHiku1Seki (x:xs) = (x * 2 - 1) * baiHiku1Seki xs

--baiHiku1Seki [1,2,3,4]の時、105を返す。

--2要素ずつ処理してゆく再帰関数。
baiHiku1accTwo [] = []
baiHiku1accTwo (x:[]) = (x * 2 - 1) : []
baiHiku1accTwo (x:y:xs) = (x * 2 - 1) : (y * 2 - 1) : baiHiku1accTwo xs

--baiHiku1accTwo [1,2,3,4]の時、[1,3,5,7]を返す。
--baiHiku1accTwo [1,2,3,4,5]の時、[1,3,5,7,9]を返す。