Вопрос по types, scheme, dynamic – Как я могу получить тип значения в схеме?

14

Я хочу функцию, которая получает тип значения во время выполнения. Пример использования:

(get-type a)

гдеa былdefined быть произвольным значением схемы.

Как мне это сделать? Или я должен реализовать это сам, используя стек condboolean?, number? так далее. ?

Ваш Ответ

4   ответа
13

В реализациях Scheme с Tiny-CLOS-подобной объектной системой вы можете просто использоватьclass-of, Вот пример сеанса в Racket с использованием Swindle:

$ 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>

И аналогично с Guile, использующим GOOPS:

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

Все ответы здесь полезны, но я думаю, что люди забыли объяснить, почему это может быть трудно; Стандарт Схемы не включает в себя статическую систему типов, поэтому можно сказать, что значения имеют только один «тип». Вещи становятся интересными в подтипах и вокруг них (например, число против числа с плавающей точкой) и типов объединения (какой тип вы даете функции, которая возвращает число или строку?)

Если вы опишите желаемое использование немного больше, вы можете обнаружить, что есть более конкретные ответы, которые помогут вам больше.

Узко: как насчет типа «числа больше нуля» и «числа с плавающей точкой»? Ни один из них не вписывается в другой. В более общем плане: вы имеете в виду определенное представление о типах и можете написать get-тип, который будет выполнять то, что вы хотите. Вы должны сделать это!
То же самое; Вы можете удалить слово «статический» из моего поста, и это все еще имеет смысл. Пример Дэнни хороший. Фактически, язык C имеет ту же самую проблему: нет "какого" типа этого значения "? оператор, потому что многие значения имеют одинаковое представление.
Я не понимаю, почему два приведенных вами примера представляют какую-либо проблему. Для числа против случая с плавающей точкой верните последний, так как он наименьший. Для случая процедуры просто верните′procedure.
Он говорит «во время выполнения», так что это не имеет ничего общего со статическими типами. Это динамические (во время выполнения) типы значений, после которых он
Вы упускаете точку зрения Джона в том смысле, что у динамических типов среды выполнения не всегда достаточно информации для устранения неоднозначности. Конкретный пример: скажем, у меня есть программа, которая работает с цветами и именами. Я могу выбрать для представления значений этих типов только строки. Затем, если я вижу слово «серый», у меня недостаточно информации, чтобы различать тип, потому что я использую то же представление.
4

Чтобы проверить тип чего-либо, просто добавьте знак вопроса после типа, например, чтобы проверить, является ли x числом:

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

Просто продолжай с этим.

Оказывается, для моего случая недостающий бит былcharacter?, Для полноты картины есть такжеvector?.
ФП конкретно спросил, есть ли альтернатива этому подходу. Кроме того, зачем использовать вложенныеifкогда вы можете использоватьcond? * Испуг *
@ewein @Chris Jester-Young что-нибудь пропустило? За(get-Type (car (string->list (number->string 5)))) это ничего не возвращает.
11

В Racket вы можете использоватьdescribe пакет от Дуга Уильямса от PLaneT. Это работает так:

> (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)
Этот пакет действительно полезен. Я хотел бы, чтобы это было частью основной ракетки.

Похожие вопросы