9. 式と文の違い (文)
Java
int[] f(int x) {
int[] res = new int[x];
for (int i = 0; i < x; i++)
res[i] = i * 2;
return res;
}
int sum(int[] xs) { ... }
// これはもちろん可能
int total = sum(f(10));
// これは出来ない
int total = sum(
int[] res = new int[x];
for (int i = 0; i < x; i++)
res[i] = i * 2;
return res;
);
10. 式と文の違い (式)
F#
let f x =
let res = Array.zeroCreate x
for i in 0..(x - 1) do
res.[i] <- i * 2
res
let sum xs = ...
// これはもちろん可能
let total = sum(f 10)
// これも可能!
let total =
sum (
let res = Array.zeroCreate 10
for i in 0..(10 - 1) do
res.[i] <- i * 2
res
)
13. さっきのコードをもう一回見てみる
let f x =
let res = Array.zeroCreate x
for i in 0..(x - 1) do
res.[i] <- i * 2 // 状態書き換えてる!
res
状態書き換えない版
let f x =
Array.init x ((*)2)
ループを自分で書く必要すらない!
→バグの抑制につながる
14. F#って静的型付き言語って言ったよね・ ?
・・
今までのコード、型書いてません。
でも、型推論によってコンパイル時に型が付いて
いたのです!
// int を受け取って int[] を返す関数
// 「int -> int[]」と記述する
let f x =
Array.init x ((*)2)
この関数にどうやって型が付いたのか見ていき
ます。
16. ((*)2) について
F#では、中置演算子を関数として扱える
2 * 4 // 8
(*) 2 4 // 8
そして、複数引数の関数に引数を「一部」与える
ことができる
let f x y = x * y
f 2 4 // 8
let g = f 2
g 4 // 8
つまり、((*)2) は「何かを 2 倍する関数」
17. 型推論のステップ
let f x =
Array.init x ((*)2)
1 Array.init は、int → (int → α) → α
[]
. 2 x は Array.init の第一引数として渡している
x の型は int
3 戻り値の型は Array.init の戻り値の型と同じ
.
f の戻り値の型はα
[]
4 掛け算「*」の型は int → int → int
((*)2) は引数を一つ与えているので、int → int
これを Array.init の第二引数として渡しているの
. で、(int → α) のαは int
全体として、f は「int → int ]
[ 」
30. 二分木の実装
Java の場合
public class BinTree {
final int value;
BinTree left = null;
BinTree right = null;
public BinTree(int value) {
this.value = value;
}
}
F#の場合
type BinTree =
| Leaf
| Node of BinTree * int * BinTree
// ↑ ↑
31. 二分探索木の探索
Java の場合
public boolean contains(int value) {
if (value == this.value)
return true;
if (value < this.value && lelft != null)
return left.contains(value);
if (this.value < value && right != null)
return right.contains(value);
return false;
}
F#の場合
let rec contains value = function
| Leaf -> false
| Node (l, v, r) when v = value -> true
| Node (l, v, r) when value < v -> contains value l
| Node (l, v, r) when v < value -> contains value r