【问题标题】:How do I get the type of a value in Scheme?如何在 Scheme 中获取值的类型?
【发布时间】:2012-07-19 18:14:48
【问题描述】:

我想要一个在运行时获取值类型的函数。使用示例:

(get-type a)

其中a 一直是defined 是一些任意的Scheme 值。

我该怎么做?还是我必须自己实现这个,使用boolean?number? 等的条件堆栈?

【问题讨论】:

    标签: dynamic types scheme


    【解决方案1】:

    在具有类似 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>
    

    【讨论】:

      【解决方案2】:

      在 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)
      

      【讨论】:

      • 这个包确实很有帮助。我希望它是核心球拍的一部分。
      【解决方案3】:

      这里的所有答案都很有帮助,但我认为人们忽略了解释为什么这可能很难; Scheme 标准不包括静态类型系统,因此不能说值只有一种“类型”。子类型(例如数字与浮点数)和联合类型(您为返回数字或字符串的函数提供什么类型?)中和周围的事情变得有趣。

      如果您更多地描述您想要的用途,您可能会发现有更具体的答案可以为您提供更多帮助。

      【讨论】:

      • 他说“在运行时”,所以这与静态类型无关。这是他追求的动态(运行时)值类型
      • 你错过了约翰的观点,因为动态运行时类型并不总是有足够的信息来消除歧义。具体示例:假设我有一个处理颜色和名称的程序。我可以选择只用字符串来表示这些类型的值。然后如果我看到“灰色”这个词,我没有足够的信息来区分类型,因为我使用的是相同的表示。
      • 同上;您可以从我的帖子中删除“静态”一词,它仍然有意义。丹尼的例子就是一个很好的例子。事实上,C 语言也有同样的问题:没有“这个值的类型是什么”运算符,因为许多值具有相同的表示。
      • 我不明白为什么您给出的两个示例会造成任何问题。对于数字与浮点数的情况,返回后者,因为它是最少的。程序案例,直接返回′procedure
      • 狭义地说:“数字大于零”和“浮点数”类型呢?这些都不适合另一个。更笼统地说:你心中有一个特定的类型概念,你当然可以编写一个 get-type 来做你想做的事。你应该这样做!
      【解决方案4】:

      要检查某事物的类型,只需在类型后添加一个问号,例如检查 x 是否为数字:

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

      请继续。

      【讨论】:

      • OP 专门询问是否有替代这种方法的方法。另外,既然可以使用cond,为什么还要使用嵌套的ifs? *难以置信*
      • @ewein @Chris Jester-Young 这是遗漏的吗?对于(get-Type (car (string-&gt;list (number-&gt;string 5)))),这不会返回任何内容。
      • 在我的情况下,丢失的位是character?。为了完整起见,还有vector?
      猜你喜欢
      • 2021-05-25
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 2017-06-25
      相关资源
      最近更新 更多