Typed Racketのお勉強 (7)
4 Types in Typed Racket (続き)
Typed Racketはパラメータ多相にも対応しています
Maybeモナドっぽいもの
(struct None ())
(struct (a) Some ([v : a]))
(define-type (Opt a) (U None (Some a)))
(struct (a) ...)
は型a
を引数に取った型の定義
型だけ作ってもモナドにはならないとは思いますが
使い方の例にはなりますね
(: find (-> Number (Listof Number) (Opt Number)))
(define (find v l)
(cond [(null? l) (None)]
[(= v (car l)) (Some v)]
[else (find v (cdr l))]))
このfind
、これで終わりじゃないよな?
当然、数以外にも適用できるようにするはず・・・
流れ的に次は多相関数
でも例はfind
じゃないな・・・
(: list-length (All (a) (-> (Listof a) Integer)))
(define (list-length l)
(if (null? l)
0
(add1 (list-length (cdr l)))))
l
の要素がなんだろうが気にしないので
どれ
> (list-length '(1 2 3 4))
- : Integer
4
> (list-length '("a" "b" "c" "d"))
- : Integer
4
こういうのはどうなるんだろう?
> (list-length '(1 2 "c" "d"))
- : Integer
4
許されるんだな
find
は放置みたいなので自分で書き直してみよう
=
は数にしか使えないので・・・
> =
- : (-> Number Number Number * Boolean) ... [Use (:print-type <expr>) to see more.]
#<procedure:=>
:print-type
してみろって言ってる
> (:print-type =)
(case->
(-> Real Real-Zero Boolean)
(-> Real-Zero Real Boolean)
(-> Exact-Number One Boolean)
(-> One Exact-Number Boolean)
(-> Exact-Number Positive-Byte Boolean)
(-> Positive-Byte Exact-Number Boolean)
(-> Exact-Number Byte Boolean)
(-> Byte Exact-Number Boolean)
(-> Exact-Number Positive-Index Boolean)
(-> Positive-Index Exact-Number Boolean)
(-> Exact-Number Index Boolean)
(-> Index Exact-Number Boolean)
(-> Exact-Number Positive-Fixnum Boolean)
(-> Positive-Fixnum Exact-Number Boolean)
(-> Exact-Number Nonnegative-Fixnum Boolean)
(-> Nonnegative-Fixnum Exact-Number Boolean)
(-> Exact-Number Negative-Fixnum Boolean)
(-> Negative-Fixnum Exact-Number Boolean)
(-> Exact-Number Nonpositive-Fixnum Boolean)
(-> Nonpositive-Fixnum Exact-Number Boolean)
(-> Exact-Number Fixnum Boolean)
(-> Fixnum Exact-Number Boolean)
(-> Exact-Number Positive-Integer Boolean)
(-> Positive-Integer Exact-Number Boolean)
(-> Exact-Number Nonnegative-Integer Boolean)
(-> Nonnegative-Integer Exact-Number Boolean)
(-> Exact-Number Negative-Integer Boolean)
(-> Negative-Integer Exact-Number Boolean)
(-> Exact-Number Nonpositive-Integer Boolean)
(-> Nonpositive-Integer Exact-Number Boolean)
(-> Exact-Number Integer Boolean)
(-> Integer Exact-Number Boolean)
(-> Exact-Number Positive-Exact-Rational Boolean)
(-> Positive-Exact-Rational Exact-Number Boolean)
(-> Exact-Number Nonnegative-Exact-Rational Boolean)
(-> Nonnegative-Exact-Rational Exact-Number Boolean)
(-> Exact-Number Negative-Exact-Rational Boolean)
(-> Negative-Exact-Rational Exact-Number Boolean)
(-> Exact-Number Nonpositive-Exact-Rational Boolean)
(-> Nonpositive-Exact-Rational Exact-Number Boolean)
(-> Exact-Number Exact-Rational Boolean)
(-> Exact-Rational Exact-Number Boolean)
(-> Exact-Number Exact-Number Boolean)
(-> Exact-Number Exact-Number Boolean)
(-> Real Real-Zero Boolean)
(-> Real-Zero Real Boolean)
(-> Real Positive-Real Boolean)
(-> Positive-Real Real Boolean)
(-> Real Nonnegative-Real Boolean)
(-> Nonnegative-Real Real Boolean)
(-> Real Negative-Real Boolean)
(-> Negative-Real Real Boolean)
(-> Real Nonpositive-Real Boolean)
(-> Nonpositive-Real Real Boolean)
(-> Real Real Boolean)
(-> Real Real Boolean)
(-> Number Number Number * Boolean))
どわ!
いろんな型の比較ができる、っていいたいの?
(-> Number Number Number * Boolean)
だけで全部カバーできてるような
気もするけど?
複数を比較できるのが(-> Number Number Number * Boolean)
だけだから
他は`(-> Number Number Number * Boolean)
から呼び出されて使われる、
って感じなのかな?
まあそれはおいといてequal?
で比較することに
> equal?
- : (-> Any Any Boolean)
#<procedure:equal?>
> (:print-type equal?)
(-> Any Any Boolean)
こっちは普通
こうね
(: find2 (All (a) (-> a (Listof a) (Opt a))))
(define (find2 v l)
(cond [(null? l) (None)]
[(equal? v (car l)) (Some v)]
[else (find2 v (cdr l))]))
お試し
> (find2 3 '(1 2 3 4))
- : (U None (Some Positive-Byte))
#<Some>
> (find2 5 '(1 2 3 4))
- : (U None (Some Positive-Byte))
#<None>
> (find2 'c '(a b c d))
- : (U None (Some (U 'c 'a 'b 'd)))
#<Some>
> (find2 'e '(a b c d))
- : (U None (Some (U 'c 'a 'b 'd 'e)))
#<None>
> (find2 '(c d) '((a b) (b c) (c d) (d e)))
- : (U None (Some (U (List 'c 'd) (List 'a 'b) (List 'b 'c) (List 'd 'e))))
#<Some>
> (find2 '(e f) '((a b) (b c) (c d) (d e)))
- : (U None
(Some
(U (List 'c 'd) (List 'a 'b) (List 'b 'c) (List 'd 'e) (List 'e 'f))))
#<None>
おk
最後、(U (List 'c 'd) (List 'a 'b) (List 'b 'c) (List 'd 'e) (List 'e 'f)))
を
返すかも、っていうのはどこまでプログラムの中身がわかってるのかなあ
(List 'e 'f)
を見つけてくるなんてすごいと言うべきか
(List 'e 'f)
なんて返さないってことがわからない程度と言うべきか