kb84tkhrのブログ

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

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)なんて返さないってことがわからない程度と言うべきか