Typed Racketのお勉強 (8)
4 Types in Typed Racket (続き)
Rest argumentsの単純なケース
(この前もちょっと出てきてましたが)
*
で0個以上の繰り返しであることを示してます
(: sum (-> Number * Number))
(define (sum . xs)
(if (null? xs)
0
(+ (car xs) (apply sum (cdr xs)))))
引数の型が異なってくる場合
(: fold-left
(All (C A B ...)
(-> (-> C A B ... B C) C (Listof A) (Listof B) ... B
C)))
(define (fold-left f i as . bss)
(if (or (null? as)
(ormap null? bss))
i
(apply fold-left
f
(apply f i (car as) (map car bss))
(cdr as)
(map cdr bss))))
わからないことがふたつ
B
は出てくる場所によって違う型を指してる?それともAny
みたいなもの?
B ... B
の最後のB
は必要?
> (fold-left + 0 '(1 2 3 4) '(5 6 7 8))
- : Integer [more precisely: Nonnegative-Integer]
36
> (fold-left (λ (i v n s) (string-append i (vector-ref v n) s))
""
(list (vector "A cat" "A dog" "A mouse")
(vector "tuna" "steak" "cheese"))
(list 0 2)
(list " does not eat " "."))
Type Checker: type mismatch
expected: String
given: Any in: i
Type Checker: Polymorphic function `vector-ref' could not be applied to arguments:
Types: VectorTop Integer -> Any
Arguments: Any Any
Expected result: String
in: (vector-ref v n)
Type Checker: type mismatch
expected: String
given: Any in: s
Type Checker: Summary: 3 errors encountered in:
i
(vector-ref v n)
s
ダメじゃないですか
例のとおりに入れたのに・・・
λ
に型を入れてやったら動いたんですけど
> (fold-left (λ ([i : String]
[v : (Vector String String String)]
[n : Integer]
[s : String]) : String
(string-append i (vector-ref v n) s))
""
(list (vector "A cat" "A dog" "A mouse")
(vector "tuna" "steak" "cheese"))
(list 0 2)
(list " does not eat " "."))
- : String
"A cat does not eat cheese."
でもめんどくさいよ?
例の通りで動かないのはどうして?
確かにこう書いてはあったけど・・・
めんどくさいよ?
こんなときには型修飾が必要と書いてあります
- 関数をdefineするとき
- lambdaを直接変数にバインドするとき
- lambdaを多相関数の引数にするとき
- ミュータブルな変数を定義するとき
単純な例では動いたんだし
B
は出てくる場所によって違う型を指してる?それともAny
みたいなもの?
エラーメッセージからするとAny
ではないっぽい気がする
B ... B
の最後のB
は必要?
取っても動いた
なんでついてるの?
もうちょっと調べないともやっとするな・・・