kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

Typed Racketのお勉強 (5)

4 Types in Typed Racket

主な基本型はInteger, Flonum, String, Char, Boolean, ->(関数)あたりですが
なんか妙に細かい型があります
数値型にPositiveとNegativeがある、くらいは理解できますが
こないだ出たZero型、One型の他にもTrue型とかある、というだけでなく
あらゆる値がすべてその値を型とできるようです

> 100
- : Integer [more precisely: Positive-Byte]
100
> (ann 100 100)
- : Integer [more precisely: 100]
100
> 0.1
- : Flonum [more precisely: Positive-Flonum]
0.1
> (ann 0.1 0.1)
- : Flonum [more precisely: 0.1]
0.1
> "aaa"
- : String
"aaa"
> (ann "aaa" "aaa")
- : "aaa"
"aaa"

これはどういう役に立つのかちょっとわかりません
型の理論とか勉強すると出てくるんでしょうか

Multiple Valueを返す場合の型は以下のようになります

> (lambda ([c : Char]) (values (string c) (char->integer c)))
- : (-> Char (values String Index))
#<procedure>

Index型というのは0からVectorのIndexの最大値までの整数を表す型らしいです

Rest Argumentのある関数の型はこの間やりました
型の後ろにアスタリスクをつけてました

Optional ArgumentやKeyword Argumentを含む関数の型は
->*を用いて書きます

デフォルト値を書いてやるとOptional引数になります

> (define (greet [given : String] [surname : String "Smith"])
    (string-append "Hello, " given " " surname))
> greet
- : (->* (String) (String) String)
#<procedure:greet>

ひとつめのカッコ内が普通のArgument、
ふたつめのカッコ内がOptional Argumentの型となります

最後にKeyword Argumentなんですが、例として

(->* (#:x Number) (#:y Number) (values Number Number))

という型が挙がっているんですけれども

> (define (kwarg #:x [x : Number] #:y [y : Number 3])
    (values x y))
> (kwarg #:x 2)
- : (values Number Number)
2
3
> (kwarg #:x 2 #:y 5)
- : (values Number Number)
2
5

という関数を作ってみたところ違う型の表示になりました

> kwarg
- : (-> #:x Number [#:y Number] (values Number Number))
#<procedure:kwarg>

例の通りの型定義をつけてやってもエラーにはならず
型の表示はさっきと変わらないので、書き方が違うだけで同じ型を表してるっぽいです

> (: kwarg (->* (#:x Number) (#:y Number) (values Number Number)))
> (define (kwarg #:x [x : Number] #:y [y : Number 3])
    (values x y))
> kwarg
- : (-> #:x Number [#:y Number] (values Number Number))
#<procedure:kwarg>