りゅうくんの備忘録

徒然なるままに思ったことを書くところ

最近の授業とかとか


書くにあたって経緯的な

最近の授業、関数型でSKIとかラムダ式とか、知らないこと+知らないこと で進んでて理解するの大変そうなーなんて思ったので、お助けになればなーって記事です。

この記事に書いてること、書いてないこと

書いてること

  • 関数型の軽い説明
  • true,falseの関数について
  • 関数型での数字の定義について

書いてないこと

書いてないやつも僕が理解したり、みんながわからない!ってなってたらまとめるかもしれない。再帰はまた今度やるかも

 

自分も細部まで理解してるわけじゃないから、間違ってたら訂正お願いします🙇

関数型の軽い説明

プログラムを関数で構築する。僕も詳しくないので一緒におべんきょしよう... この辺の記事とか分かりやすそうだなって思いましたまる

javascriptは純粋な関数型の言語じゃあないけど、一応関数型の性質を持ってるよーってことで授業では使ってるぽい。

javaでSystem.out.printlnを変数に代入して使えないけどJSのconsole.logとかPython3のprintは変数に入れても使える的な感じだろうか

js

f:id:Ryu1kun:20180522091034p:plain

Python3

f:id:Ryu1kun:20180522091038p:plain

Java

f:id:Ryu1kun:20180522092649p:plain

Javaでも出来るかもしれないけど、僕やり方知らないです...

true,falseの関数

これはif文と比べて考えるとちょっと分かりやすいです。

if(条件式){trueの場合の処理}else{falseの場合の処理}って書き方をします。

trueなら前をfalseなら後ろを返してます(語弊がありそう)

次に関数っぽくかくと

const T = x => y => x
const F = x => y => y

ってなります

trueなら1つめの引数を、falseなら2つめの引数を返してます。この動きをif文の挙動になぞらえて考えてみるとわかるかもしれない...

関数型での数字の定義について

omasせんせ曰く、関数型では数字も関数。数字も引数をとるそうです

数字を関数型で表すとこうなるそうです

const zero = s => z => z;
const one = s => z => s(z);
const two = s => z => s(s(z));

まずoneっていう関数のお話をします。

関数oneは引数を2つ取って、第一引数には(x => x+1),第二引数には(0)が入ります。 returnする形がs(z)なので、これに当てはめて考えてみると
(x => x+1)(0)ってなります!!
この式(x=>x+1)を見てみるとxって引数を取ってx+1を返すって見れるので、さらに当てはめて考えてみる
(x=>x+1)でxが0なので帰ってくる値は0+1で1が帰ってきます!

なので関数oneをone(x=>x+1)(0)って使うと、 1 って帰ってくる!!

同様に関数twoも考える

関数twoは関数oneと同じく引数を2つ取る。引数に入るものは一緒で,sには(x=>x+1),zには(0)が入る!
関数twoはs(s(z))を返し、sには(x=>x+1),zには(0)が入るので、(x=>x+1)(x=>x+1)(0)になるね。

これを書き下していこー。

(x => x+1)が(x => x+1)を引数に取るので,( (x => x+1)+1 )が返ってくる値になる
次に,(x=>x+1+1)が引数に(0)を取るので,(0+1+1)で最終的に返ってくる値は 2 ってなるんすよ

ついでにzeroは第二引数の(0)をそのまま返せばいいのでzero(x=>x+1)(0) から 0 って感じです

oneとtwoを比べてs()が増えたら+1されるってのがわかったからthreeの関数とかもう作れるね

最後にaddっていう足し算する関数を書いてみようーー

add(one)(two)(x => x+1)(0) って実行したら 3 って出力をもらう感じの関数を作ります。

addは引数を4つもってるので const add = n => m => s => z => { //処理の実装 } って感じの形になるます

肝心の処理の実装なんだけど、oneとtwoを比べてs()の数を増やせば、返ってくる値も大きくなることがわかった。ということは、10って関数を作りたいときは、zをsで10回囲めばよくて、100って数を関数で書きたいときは、s()でzを100回囲んでやればいいわけ。
つまり、nって数字を実装したいときはzをs()でn回囲めばいい!!!
この性質を利用して足し算する処理を作っていきます。

1+2は3です。1に1を2回足すから3になるんですよ。

つまり、n+mはnに1をm回足せば答えが出るわけですね!!(ここ大事)

add って関数は引数に(数字 == n)(足す数字 == m)(x => x+1)(0)を取るので、数字に1を足す数字分足せばいいわけです!

m(s(n(s)(z))) こうなりますね!!詳しく解説していきます。
n(s)(z)は上で説明した通りnという数字のを表しています。m(s ))でmという数字回分sするというって表現です。
sはx => x+1、sをざっくり説明すると1を足すこと,で,n(s)(z)でn回分0に1を足す,m(s( ))でm回分1を足す,と読めるようになります。

n回0に1を足した数字に,m回分1を足した数字を返す
つまり n + mを返すので足し算がこれで実装できます!!

あとがき

思い出しながら書いたので、ちょいちょいミスってるところがあるかもしれないので、見つけたら報告くれると嬉しいです!!
学校の方は、けっこー授業の内容が難しくなってきましたが、共に頑張りましょーー