Racket言語:Typed Racketをraco pkg installで入れるときは、"typed-racket"と指定する


RacketにTyped Racketを入れるときに、少しハマったので備忘録を残します。

TypedRacketの特徴については、次のサイト他があります。

インストール前

#lang typed/racketを冒頭に宣言したスクリプトを実行すると、ライブラリが見つからない(not found)エラーが吐かれた。

Terminal
electron@diynoMacBook-Pro ~ % cat test.rkt
#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))))))

electron@diynoMacBook-Pro ~ %
Terminal
electron@diynoMacBook-Pro ~ % racket test.rkt
standard-module-name-resolver: collection not found
  for module path: typed/racket/lang/reader
  collection: "typed/racket/lang"
  in collection directories:
   /Users/electron/Library/Racket/8.2/collects
   /usr/local/Cellar/minimal-racket/8.2/share/racket/collects/
   /usr/local/Cellar/minimal-racket/8.2/share/racket/pkgs/racket-lib
electron@diynoMacBook-Pro ~ %

raco pkg installするときは、"typed-racket"と指定する

You can also manually install it from the main package catalog with the following command:

raco pkg install typed-racket

インストール実行

raco pkg install typed-racketを実行します。

Terminal
electron@diynoMacBook-Pro ~ % raco pkg install typed-racket
Resolving "typed-racket" via https://download.racket-lang.org/releases/8.2/catalog/
Downloading https://download.racket-lang.org/releases/8.2/pkgs/typed-racket.zip
The following uninstalled packages are listed as dependencies of typed-racket:
   typed-racket-lib
   typed-racket-doc
00: Resolving "typed-racket-lib" via https://download.racket-lang.org/releases/8.2/catalog/
Resolving "typed-racket-doc" via https://download.racket-lang.org/releases/8.2/catalog/
Downloading https://download.racket-lang.org/releases/8.2/pkgs/typed-racket-lib.zip
Downloading https://download.racket-lang.org/releases/8.2/pkgs/typed-racket-doc.zip
The following uninstalled packages are listed as dependencies of typed-racket-lib:
   base
   source-syntax
   pconvert-lib
   compatibility-lib
   string-constants-lib
Would you like to install these dependencies? [Y/n/a/c/?] a
00: Resolving "base" via https://download.racket-lang.org/releases/8.2/catalog/
01: Resolving "source-syntax" via https://download.racket-lang.org/releases/8.2/catalog/
02: Resolving "pconvert-lib" via https://download.racket-lang.org/releases/8.2/catalog/

( 省略 )

raco setup: 3 rendering: <pkgs>/racket-index/scribblings/main/search.scrbl
raco setup: --- installing collections ---                         [16:31:14]
raco setup: installing: <collects>/racket
raco setup: installing: <pkgs>/gui-lib/mred
raco setup: installing: <pkgs>/gui-lib/racket/gui
raco setup: installing: <pkgs>/racket-doc/help
raco setup: --- post-installing collections ---                    [16:31:14]
electron@diynoMacBook-Pro ~ % 

動作確認

今度は、スクリプトファイルを動かすことができきました。

Terminal
electron@diynoMacBook-Pro ~ % cat test.rkt
#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))))))

electron@diynoMacBook-Pro ~ % 
Terminal
electron@diynoMacBook-Pro ~ % racket test.rkt
electron@diynoMacBook-Pro ~ %

エラーなしに、実行終了。
関数定義しか行なっっていない(値への適用はしていない)ので、標準出力への出力物なし。

対話型インタプリタで実行

Terminal
electron@diynoMacBook-Pro ~ % racket -I typed/racket
Welcome to Racket v8.2 [cs].
> (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))))))
> 

関数定義しか行なっていない(値への適用はしていない)ので、返り値はなし。

次のサイトにあるコードも、REPL環境で問題なく動きました。

Terminal
> (module m typed/racket
      (provide Radians radians f)
      (define-new-subtype Radians (radians Real))
      (: f : [Radians -> Real])
      (define (f a)
        (sin a)))
> (require 'm)
> (radians 0)
0
> (f (radians 0))
0
> 

GitHubに上がっている次のコードも問題なく動きました。

github.com/racket/typed-racket/blob/master/typed-racket-test/succeed/refinement-even.rkt
#lang typed-scheme

(declare-refinement even?)
(define-type-alias Even (Refinement even?))

(: x Integer)
(define x 4)

(: y Even)
(define y (if (even? x) x (error 'bad)))

(: f (Even -> String))
(define (f e) (format "~a" e))

(f y)

raco installでtyped-schemeを探しましたが、見つかりませんでした。

Terminal
electron@diynoMacBook-Pro ~ % raco pkg install typed-scheme
Resolving "typed-scheme" via https://download.racket-lang.org/releases/8.2/catalog/
Resolving "typed-scheme" via https://pkgs.racket-lang.org
Resolving "typed-scheme" via https://planet-compats.racket-lang.org
raco pkg install: cannot find package on catalogs
  package: typed-scheme
electron@diynoMacBook-Pro 

typed-schemeを陽に入れなくても、動きました。

Terminal
electron@diynoMacBook-Pro ~ % racket -I typed/scheme    
Welcome to Racket v8.2 [cs].
> (declare-refinement even?)
> (define-type-alias Even (Refinement even?))
> (: x Integer)
> (define x 4)
> 
  (: y Even)
> (define y (if (even? x) x (error 'bad)))
; readline-input:7:24: Type Checker: type mismatch
;   expected: Even
;   given: Integer
;   in: x
; [,bt for context]
> (: y Even)
> (define y (if (even? x) x (error 'bad)))
; readline-input:9:24: Type Checker: type mismatch
;   expected: Even
;   given: Integer
;   in: x
; [,bt for context]
> (: f (Even -> String))
> (define (f e) (format "~a" e))
> (f y)
; y: undefined;
;  cannot reference an identifier before its definition
;   in module: top-level
; [,bt for context]
> (exit)
electron@diynoMacBook-Pro ~ % 
  • 意図した通りに動きました。
  • 以下では、error関数を実行しているので、実行エラーが起きています(意図した通りの挙動です)
> > (define y (if (even? x) x (error 'bad)))

スクリプトファイルに書いて、呼び出し実行してみます。

Terminal
electron@diynoMacBook-Pro ~ % vim refinement-even.rkt
electron@diynoMacBook-Pro ~ % cat refinement-even.rkt 
#lang typed-scheme

(declare-refinement even?)
(define-type-alias Even (Refinement even?))

(: x Integer)
(define x 4)

(: y Even)
(define y (if (even? x) x (error 'bad)))

(: f (Even -> String))
(define (f e) (format "~a" e))

(f y)
electron@diynoMacBook-Pro ~ % 
Terminal
electron@diynoMacBook-Pro ~ % racket refinement-even.rkt 
"4"
electron@diynoMacBook-Pro ~ %