Typed Racketのお勉強 (1)
Typed RacketはRacketに型を付けたものです
The Typed Racket Guideを見ながら勉強していきます
詳細はThe Typed Racket Referenceに
1 Quick Start
とりあえずこれをやれと
- ソース先頭の
#lang racket
を#lang typed/racket
に変える (require mod)
を(require typed/mod)
に変える- Structureの定義およびトップレベルの定義を型で修飾する
例
#lang typed/racket
(struct pt ([x : Real] [y : Real]))
(: distance (-> pt pt Real))
(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
->
が関数ってことですね
どことなくHaskellっぽい
どれどれ
> (distance (pt 0 0) (pt 3 4))
- : Real
5
REPLは値だけでなく型も表示してくれます
ちゃんと型チェックしてくれているか
> (distance 3 4)
Type Checker: type mismatch
expected: pt
given: Positive-Byte in: 3
Type Checker: type mismatch
expected: pt
given: Positive-Byte in: 4
Type Checker: Summary: 2 errors encountered in:
3
4
よしよし
2 Beginning Typed Racket
#lang typed/racket
はTyped Racketを使うよという宣言struct
には型修飾を付ける(-> pt pt Real)
は関数の型->
が関数のしるし- 最後の型(
Real
)が戻り値の型
関数自身を評価すれば関数自身の型も表示できます
> distance
- : (-> pt pt Real)
#<procedure:distance>
:print-type
も使えます
> (:print-type distance)
(-> pt pt Real)
こっちの方が表示はすっきり
2.1 Datatypes and Unions
U
はUnion型の定義define-type
で型に名前をつける
こう
(define-type Tree (U leaf node))
(struct leaf ([val : Number]))
(struct node ([left : Tree] [right : Tree]))
参照はこんな感じ
struct
で定義したときにleft-val
やnode-left
も勝手に定義されています
(define t1 (node (leaf 1) (leaf 2)))
(leaf-val (node-left t1))
関数定義
組み込み型でも自分で定義した型でも書き方は同じ
(: tree-height (-> Tree Integer))
(define (tree-height t)
(cond ((leaf? t) 1)
(else (max (+ (tree-height (node-left t)) 1)
(+ (tree-height (node-right t)) 1)))))
(leaf? t)
はt
がleaf
型かどうかを判定しています
これも勝手に定義されます