大人のお型付け
DESCRIPTION
CLR/H ナイトセミナー #2 ( http://atnd.org/events/36571 ) のTypeScriptのセッションで使用した資料ですTRANSCRIPT
大人のお型付け
TypeScript + αの お話Nobuhisa Koizumi
このセッションには
F# の話題が含まれている危険性があります
なぜK泉さんが ”TypeScript” なのか
自分でも良くわからない・・・
2月1日のやり取り
注意事項
TypeScript をよく知りません
間違いを含んでいる可能性があります
高度な質問は聞こえないフリをします
TypeScript
(弱い)静的型付けJavaScript (ECMAScript)
Open Source
http://typescript.codeplex.com/
> git clone https://git01.codeplex.com/typescript
コンパイラ(tsc)がJavaScriptを生成
TypeScript – 個人的感想 –
意外と学習コストは大きい
F#のほうが楽しい!
JavaScriptよりは安全
“Type”Script
すべての型は、プログラマのために・・・
“テスト”としての型
“ドキュメント”としての型
テストとしての型
型の整合性に関するテストをコンパイラが代行
動的型付けの場合は自己責任
3.14 + True / “A”
x + y / z
ドキュメントとしての型 (F#の例)
型は貴重な情報源
型からプログラムを予想できる
fst : „a * „b -> „a
„a -> („a -> „b) -> „b
お型付けの作法
TypeScript の言語仕様を概観していきます
変数
var one: number = 1;var two: string = "two";
var three = 3.0; // 型推論(number)var four: number; // Undefined Type
関数の定義
function twice(x: number): number {return x * 2;
}
function identity(x) {return x;
}
(x: number) => number
(x: any) => any
ちなみに F# だと ...
let identity x = x
val identity : ‘a -> ‘a
ラムダ式 (arrow function expression)
// 従来var f0 = function (x: number) { return x * x; }
var f1 = (x: number) => { return x * x }var f2 = (x: number) => x * x;
高階関数の例
function apply(f: (x: number) => number, x: number) {
return f(x);}
// F#let apply f x = f x
クラス定義
class MyClass1 {public x: number;private y: number;
constructor(x: number, y: number) {this.x = x;this.y = y;
}}
クラス定義
class MyClass2 {constructor(public x: number, private y: number){ }
}
クラス定義
class MyClass3 {public value: number = 0;private message = "fsharp"; // 型推論
public showMessage(): void {alert(this.message);
}public getTwice() { // "() => number" に推論される
return this.value * 2;}
}
継承・オーバーライ
ドclass ML {
constructor(private message: string) { }public showMessage() { alert(this.message); }
}
class OCaml extends ML {constructor() { super("hello, OCaml"); }
}
class FSharp extends OCaml {public showMessage() { alert("F#!F#!"); } // ※
}
function run() {var x: ML = new FSharp();x.showMessage();
}
オブジェクト型
var o: {prop: number;func: () => void;
};
o = { prop: 10, func: () => alert("hello") };
無名。オブジェクト型リテラルによって仕様を記述できる。
インターフェイス!?
interface Body {weight: number;height: number;
}
function calcBMI(x: Body) {var h = x.height / 100.0;return x.weight / (h * h);
}
オブジェクト型に名前を付けたもの
構造的サブタイピング(構造的部分型)
Structural Subtyping
構造的部分型と呼ばれることが多い
平たく言うと、静的Duck Typing
C++, OCaml, Scala, F# などでも
Typ
eSc
ript
interface Wolf {howl: () => string;
}function howl(x: Wolf) {
alert(x.howl());}
class WolfDog {public howl() { return "bowwow!"; }
}
var mrchildren = { howl: () => "HOWL!" } // λ...
function start() {howl(new WolfDog());howl(mrchildren);
}
Sc
ala
object Main {type Wolf = { def howl(): Unit }
def howl(x: Wolf) {println(x.howl())
}
class WolfDog {def howl() = println("bowwow!")
}class MrChildren {
def howl() = println("HOWL!")}
def main(args: Array[String]) {howl(new WolfDog())howl(new MrChildren())
}}
F#
let inline howl x =(^a : (member Howl : unit -> unit) x)
type WolfDog() = // クラスmember this.Howl() = printfn "bowwow!"
type MrChildren = MrChildren // 判別共用体with member this.Howl() = printfn "HOWL!"
let run () =howl <| WolfDog()howl MrChildren
モジュール定義
module MyModule { // 内部モジュールの例function myFunction1() { }export function myFunction2 { }
class MyClass1 { }export class MyClass2 { }
}
内部モジュール、外部モジュールの2つがある
F# に似てるね!
module MyModule =let private myFunction1 () = ()let myFunction2 () = ()
type private MyClass1() = class endtype MyClass2() = class end
リンク
TypeScript クイックガイド (@KDKTN さん)
http://phyzkit.net/typescript/
仕様書
http://go.microsoft.com/fwlink/?LinkId=267121 (.docx)
http://go.microsoft.com/fwlink/?LinkId=267238 (.pdf)
大人のお型付け
おしまいNobuhisa Koizumi