束縛
まだ教科書読み初めたばっかだけど、勉強のログを取ることは重要ということで、適当に記録してく。
束縛
「○○変数の束縛」というように使うようだ。Ocamlの場合は、代入というのではなく「束縛」というらしい。
束縛はletを使う。束縛された変数を使用して計算を行うことができる
以降、「#」で始まる行は入力を表し、他はインタープリタからの出力を表す。
# let pi = 3.1415926535;; val pi : float = 3.1415926535 # 2.0 *. pi *. 4.0;; (* 半径4の円周 *) - : float = 25.132741228
関数
関数についても束縛というのだそうだ。
# let enshu r = 2.0 *. pi *. r;; val enshu : float -> float = <fun> # enshu 4.0 - : float = 25.132741228
匿名関数
他の言語では無名関数と呼ばれていたりもする。
letで定義しているのは、実際にはfunを使用した式の略式記法なのだそうだ。
# let enshu = fun n -> 2.0 *. pi *. n;; val enshu : float -> float = <fun> # enshu 4.0;; - : float = 25.132741228
perlでやると、
use constant PI => 3.1415926535; my $enshu = sub{ my ($r) = @_; 2.0 * PI * $r; }; $enshu->(4.0);
匿名関数(無名関数)が使えると何がうれしいかというと、関数を引数にする関数を作れるということかな。
カリー化
引数の一部を束縛した関数を返す。
まだよくわかっていないけど、複数の引数を渡したい場合などで、一部の引数のみ先に処理し、次の引数を処理する為の関数を返すというのがカリー化という認識。
なお、Ocamlでは、引数は一つしか渡せない。複数の引数を渡したいときにはタプル(組)を使用する。
カリー化を使わないconcat
# let concat (s1,s2) = s1 ^ s2 ^ s1;; val concat : string * string -> string = <fun> # concat ("abc","def");; - : string = "abcdefabc"
perlでは
my $concat = sub{ my ($s1,$s2) = @_; "$s1$s2$s1"; }; $concat->("abc","def");
カリー化を使うconcat
let concat_curry s1 = fun s2 -> s1 ^ s2 ^ s1;; val concat_curry : string -> string -> string = <fun> # (concat_curry "abc") "def";; - : string = "abcdefabc"
perlでは、第一引数を束縛し、次に渡された第一引数を処理するクロージャを返す。
my $concat_curry = sub{ my ($s1) = @_; sub{ my ($s2) = @_; "$s1$s2$s1"; } }; $concat_curry->("abc")("def");