FreeBSDな日々
http://w.atwiki.jp/aomori5/
FreeBSDな日々ja2007-03-10T21:11:41+09:001173528701MLの基礎(7)高階関数(2)
https://w.atwiki.jp/aomori5/pages/15.html
・リストを扱う高階関数
さて、次につぎのような高階関数を定義してみよう
map (fn n=>2n) [1,2,3,4] (->[2,4,6,8]
filter (fn n=> (n mod 2)=0) [1,2,3,4] (-> [2,4])
mapは、リストの各要素に関数fを適用した結果をリストとして返す関数。
[a1, a2, a3, ... ,an]--map f-->[f(a1), f(a2), f(a3),...,f(a4)]
filter ある条件を満たす要素のみを要素とするリストを返す関数。
[a1, a2, a3, .. ,an]--filter pred-->[a2, a5,...,an]
n mod 2はnを2で割ったあまり、これが0の時、true.
問 map filterを定義せよ。
#comment()
2007-03-10T21:11:41+09:001173528701MLの基礎(6)高階関数
https://w.atwiki.jp/aomori5/pages/14.html
・高階関数 first order function
関数を返す関数
いよいよ、関数型言語の佳境。
text p.56-60
f m n = m + n
と定義し、さらに、
g = f mと定義する。
すると、
g 1 = 3+ 1
g 2 = 3+2
となる。
・関数式 text p.61
名前のない関数、本来は、これが関数の定義である。
(fn x=>x+1)3*10; (->40)
val plusone = fn x=>x+1;
として、名前をつけ、
plusone 3 *10を実行してみよ。同じ結果が得られる。
summationの例をパターンマッチングで書くと、
fun summation f 1 = f 1
| summation f n = f n + summation f (n-1);
1+2+3+4+...+10
1^2 + 2^2 +3^2 + +10^2
1^3 + 2^3 + 3^3 + 10^3
をsummationと関数式を使って、それぞれ書いてみると、
summation (fn n=>n) 10
summation (fn n=> n*n) 10
summation (fn n=> n*n*n) 10
とかける。
1回しか使わない場合、いちいち関数に名前をつけずにすむので重宝する。
#comment() 2007-03-10T21:11:06+09:001173528666MLの基礎(5)リストを扱う関数
https://w.atwiki.jp/aomori5/pages/13.html
・リストを扱う3つの基本関数
null 空リストかどうかを判定
tl リストの先頭部分を除いた残りのリストtailを返す関数
hd リストの先頭部分headを返す関数
これらは、標準で定義されているので、
my_null my_tl my_hdとして、関数を定義せよ。(問1)
(ヒント:空リストは [] or nil
空でないリストのパターンマッチング (h::t)
要素が一個のパターンマッチング [x])
問2 次の関数を定義せよ。
length リストの長さ(要素の数)を示す関数
sumList リストの値(整数)の合計値を示す関数
member ある要素がリストに含まれているかどうかを判定する関数
(ヒント:length については、hd で先頭部分があれば、1を加え、
(1だけを加えるケースと1を加えて、recursiveに定義するケースとがある。)
、[]になれば0を加える。ケース分けは3つ。)
問3 次の関数を定義せよ。
plus 2つのリストを合わせて、新たなリストを返す関数。
例) plus [1,2,3] [4,5,6] -> [1,2,3,4,5,6]
#comment() 2007-03-10T21:10:18+09:001173528618MLの基礎(4)リスト構造
https://w.atwiki.jp/aomori5/pages/12.html
・リスト構造
関数型言語で最も重要なリスト構造について。
text p.93-p.99
リストは先頭要素を取り除いた残りもリスト。リストの先頭にある値(要素)を付け加えたものもリスト。また、終わりはnil。これが、リスト構造の定義そのものである。
リスト構造は、中に入れ子のようにリスト構造を含んでいる。
だから、帰納的関数と相性があう。
視覚的には、
(v1,(v2,(v3,(.....(vn,nil)...)である。
これをML風に書くと、
v1::v2::v3:: ... ::vn::nil
とか、
[v1,v2,v3,.....,vn]とかく。
実は、:: はリストを作る関数である。
2::[3,4]; (-> [2,3,4])リスト[3,4]の先頭に2を追加し、新たなリストを作る。
2007-03-07T00:03:34+09:001173193414MLの基礎(3)
https://w.atwiki.jp/aomori5/pages/11.html
・変数関係の補足
val pi=3.14 は、いわゆる、変数への代入ではない。
MLでは、static bindingといって、piという変数に3.14という値をbind
結びつけている。
MLは、一度、bindするとその値は変わることがない。
しかし、
val pi=0.0;
とすると、piは0.0と評価される。
実は、piの再定義によって、古いpiのbindingがきえたわけではなく、隠されただけという。
例えば、
val pi=3.14;
val area=pi*3.0*3.0; (-> 28.26)
val pi=0.0;
area; (-> 28.26)(0とはならない)
変数名とそれにbindされている値の組み合わせの集合を環境(environment)という。
areaの環境ではpi=3.14であり、その外でpiの値を再定義しても、
areaの環境には影響がない。static binding
関数の場合も同様である。
val y=20;
fun f x = x + y;
f 3 ; (->23)
val y =99;
f 3 ;(->23)(102とはならない)
#comment() 2007-03-06T23:48:29+09:001173192509MLの基礎(2)
https://w.atwiki.jp/aomori5/pages/10.html
text p.42-p.45
・帰納的関数(recursive function)
たとえば、
sum = 1+2+3+....+n
を定義するとき、関数型言語ではよく次のパターンを使う。
fun sum n = n + sum(n-1)
つまり、sum = n + (1+2+...+(n-1))
このsum(n-1)を繰り返し、適用(評価することで)
sum = n + (n-1)+...+ 2 + 1
を得る。
例 sum 5 =>5 + sum(4) => 5+ 4 +sum(3) => 5+4+3+sum(2)
=> 5+4+3+2+sum(1) => 5+4+3+2+1
このように、関数の定義に自分自身が含まれる場合を
帰納的定義という。
ただ、先に定義は不完全な定義である。n-1が永遠に評価されるので、
繰り返しが止まることがない。
停止条件 (base case) は、n=0のとき、このとき、0を与えればよい。
かくして、次のように定義される。
fun sum n = if n = 0 then 0 else n + sum(n-1)
ここで、停止条件が最初に来ているのがみそである。
if文だからよいが、ケース分けの場合は必ず最初にくる必要がある。
また、MLはパターンマッチングが強力であり、これを使うと、
fun sum 0 = 0 | sum n = n + sum(n-1)
と書ける。これは、
sum 0 は0と評価(置き換え)し、それ以外、sum n は n+sum(n-1)と評価(置き換え)するという意味である。
この場合は、停止条件を先に書かないと永遠に繰り返されることが一目瞭然だろう。 2007-03-06T23:28:50+09:001173191330MLの基礎(1)
https://w.atwiki.jp/aomori5/pages/9.html
テクストとしては、
http://www.pllab.riec.tohoku.ac.jp/smlsharp/smlIntroSlidesJP.pdf
を使用することとする。
text p1-p29
・型 type
MLの扱うデータは、いくつかの型 type に分類される。
数(整数 int 、実数 real)、文字(文字列、文字定数)、真理値(true,false)、その他
ここでは、当面 整数と真理値(boolean)のみ扱うこととする。
text p.30-34
・変数 variable
あるデータに名前を付けるには valを用いる。
val pi=3.14;
val name = "Osawa";
text p.35-p.40
・関数 function
関数の定義は、
fun f p = body ;
f : function name
p : parameter(引数)
b : body(関数本体)
例)fun double x = x * 2 ;
double 2; => 4
(注)f p は f(p)と同じ。
MLは型が重要であり、pの型を指定する必要があるとき
(指定しないとエラーがでるとき)は、
fun square x : real = x * x;
また、bodyの型(関数が返す値の型)を指定するときは、
fun square x = x * x : real;
とかく。
fun double x = x * 2;
でエラーがでなかったのは、2がint型であることから、
引数をint型とMLが推定できたため。
仮に、 fun double x = x * 2.0;
とすると、real型と推定するはず。
型についての注意。real型で宣言すると、整数をパラメーターに
入力すると、型が違うと表示される。
real type と int type は別物の扱い。
(なぜか、要研究)
#comment() 2007-03-06T09:38:02+09:001173141482ML勉強会の準備
https://w.atwiki.jp/aomori5/pages/8.html
準備としては、
smlのインストール。
そのほか、エディターの設定ファイルとしては、
emacs では、sml-mode.elがあるらしい。
また、vim用もある。
http://www.cs.cornell.edu/course/cs312/
参照。
#comment() 2007-03-02T14:09:13+09:001172812153ML勉強会開始
https://w.atwiki.jp/aomori5/pages/7.html
3/1/2007
ML勉強会開始
言語としては、Standard ML of New Jersyを用いる。
windows版もあるので、適宜、探してインストールしてください。
日本語の教科書としては、「Standard ML 入門」(大堀)がある。
型理論を学ぶ前に、とりあえず、関数型言語になれることから
出発する。
#comment() 2007-03-02T14:08:52+09:001172812132portsでインストール
https://w.atwiki.jp/aomori5/pages/6.html
**Portsでアプリケーションをインストール
(注)suから作業
1.準備
(1) /etc/make.confの設定
SUPHOST= cvsup.jp.FreeBSD.org で
cvsup, cvsup1~cvsup6(?)まで選択可能。
(2) CVSupのインストール
# cd /usr/ports/net/dvsup-without-gui
# make install clean
2.portsのアップデート
# cd /usr/ports
# make update
# make fetchindex
3.アプリケーションのインストール
(1) LaTeX
# cd /usr/ports/japanese/teTeX
# make install clean
# cd /usr/ports/print/dvipdfmx
# make install clean
xpdf 2006-10-15T13:01:51+09:001160884911