web-dev-qa-db-ja.com

Schemeで値の型を取得するにはどうすればよいですか?

実行時に値の型を取得する関数が必要です。使用例:

(get-type a)

ここで、adefinedであり、任意のスキーム値です。

どうすればよいですか?または、boolean?number?などのcondスタックを使用して、これを自分で実装する必要がありますか?

18
Matt Fenwick

Tiny-CLOSのようなオブジェクトシステムを使用したSchemeの実装では、class-ofを使用できます。 Swindleを使用したRacketのサンプルセッションは次のとおりです。

$ racket -I swindle
Welcome to Racket v5.2.1.
-> (class-of 42)
#<primitive-class:exact-integer>
-> (class-of #t)
#<primitive-class:boolean>
-> (class-of 'foo)
#<primitive-class:symbol>
-> (class-of "bar")
#<primitive-class:immutable-string>

同様に、GOOPSを使用するGuileの場合:

scheme@(guile-user)> ,use (oop goops)
scheme@(guile-user)> (class-of 42)
$1 = #<<class> <integer> 14d6a50>
scheme@(guile-user)> (class-of #t)
$2 = #<<class> <boolean> 14c0000>
scheme@(guile-user)> (class-of 'foo)
$3 = #<<class> <symbol> 14d3a50>
scheme@(guile-user)> (class-of "bar")
$4 = #<<class> <string> 14d3b40>
13

Racketでは、PLaneTのDoug Williamsによる describe パッケージを使用できます。それはこのように動作します:

> (require (planet williams/describe/describe))
> (variant (λ (x) x))
'procedure
> (describe #\a)
#\a is the character whose code-point number is 97(#x61) and
general category is ’ll (letter, lowercase)
12

ここでの答えはすべて役に立ちますが、なぜこれが難しいのかを説明するのを怠っていると思います。 Scheme標準には静的型システムが含まれていないため、値が1つの「型」だけであるとは言えません。サブタイプ(数値と浮動小数点数など)と共用体タイプ(数値または文字列のいずれかを返す関数にどのタイプを指定しますか?)とその周辺で物事が面白くなります。

あなたが望む使用法をもう少し説明すると、あなたはあなたをもっと助けるより具体的な答えがあることに気付くかもしれません。

7
John Clements

何かのタイプを確認するには、タイプの後に疑問符を追加します。たとえば、xが数値かどうかを確認します。

(define get-Type
  (lambda (x)
    (cond ((number? x) "Number")
          ((pair? x) "Pair")
          ((string? x) "String")
          ((list? x) "List")))) 

それを続けてください。

4
ewein