18. 例)「抵抗」の型を機能拡張する場合
type resistor = {
value : int32;
colorCode : string []
}
let showColorCode (r : resistor) =
... // ★
let sum (r1 : resistor) (r2 : resistor) : int32 =
r1.value + r2.value // ★★
定格電力(power limit)を指定して、印可可能な
最大電圧を計算できるようにしたい!
19. 例)「抵抗」の型を機能拡張する場合
type resistor = {
value : int32;
colorCode : string []
}
let showColorCode (r : resistor) =
... // ★
let sum (r1 : resistor) (r2 : resistor) : int32 =
r1.value + r2.value // ★★
type resistorEx = {
value : int32;
colorCode : string []
powerLimit : int;
}
or
type resistorEx = {
base : resistor;
powerLimit : int;
}
let showColorCodeEx (r : resistorEx) =
...
let sum (r1 : resistor) (r2 : resistor) : int32 =
…
★や★★と全く同じコードを
書かなければいけない!
かといって、既存のコードを
直接書き換えたくない。
20. 例)「抵抗」の型を機能拡張する場合
type resistor(v:int32, cc:string []) =
class
let valueV = v
let colorCodeV = cc
member this.value = vaueV;
member this.colorCode = colorCodeV;
member this.sum(r2 : resistor) : int32 =
this.value + r2.value
...
end
}
type resistorEx(v:int32, cc:string [], pl:int) =
class
inherit resistor(v, cc)
let powerLimitV = pl
member this.powerLimit = powerLimitV
end
resistorEx 型の値(オブジェクト;
クラスのインスタンス)に対して
は、value, colorCode, sum() を呼
び出せる。
21.
22. F# の場合
> let mul x y = x * y;;
val mul : x:int -> y:int -> int
> let mul (x:'a) (y:'a) = x * y;;
val mul : x:int -> y:int -> int
> mul:('a -> 'a -> 'a) = (*);;
stdin(xx,xx): warning FS0064: This construct causes code to be less generic
than indicated by the type annotations. The type variable 'a has been
constrained to be type 'int'.
四則演算を行う関数を定義しようと
すると、int 型に型推論されてしま
い、総称関数を作れない!
23. F# の場合
こうすれば OK。
let inline mul (x:'a) (y:'a) : 'a = x * y;;
val inline mul :
x: ^a -> y: ^a -> ^a when ^a : (static member ( * ) : ^a * ^a -> ^a)
> let muli:(int -> int -> int) = mul;;
val muli : (int -> int -> int)
> let mulf:(float -> float -> float) = mul;;
val mulf : (float -> float -> float)
> muli 3 5;;
val it : int = 15
> mulf 3. 5.;;
val it : float = 15.0
> mul 3 5;;
val it : int = 15
> mul 3. 5.;;
val it : float = 15.0
24. Haskell の場合
Prelude> :set +m
Prelude> data Point = P { x :: Float, y :: Float }
Prelude> let p1 = P { x = 3.0, y = 4.0 }
Prelude> let p2 = P { x = 5.0, y = 6.0 }
Prelude> p1 + p2
<interactive>:5:4:
No instance for (Num Point) arising from a use of `+'
Possible fix: add an instance declaration for (Num Point)
In the expression: p1 + p2
In an equation for `it': it = p1 + p2
Prelude> instance Num Point where (P x1 y1) + (P x2 y2) = (P (x1 + x2) (y1 + y2))
※ '*', 'abs', 'signum', 'fromInteger' が定義されていないという警告が出る。
Prelude> let p3 = p1 + p2
Prelude> x p3
8.0
Prelude> y p3
10.0