【问题标题】:How to use typed scheme/racket如何使用类型化方案/球拍
【发布时间】:2016-02-24 18:06:29
【问题描述】:

我正在尝试学习类型化的方案/球拍(?)。下面我有一个来自我的代码的例子:

#lang typed/racket
(: add (Real Real -> Real))
(define (add x y)
  (+ x y))

我想实现一个“检查”过程,它检查一个运算符是否允许使用两种数据类型。例如,

(check '(+ int int))

应该会导致

int

但是

(check '(* int (+ real int)))

应该是这样的:

运算符“+”必须有两个相同(数字)类型的操作数。

即check应该取一个list。

问题:

如何实现“检查”?首先,我虽然“好的,我有一个列表,所以让我们使用 car 和 cdr”来获取运算符和操作数,但它不起作用,我什至不知道为什么它不起作用。我也考虑过像 (if (and (= xy) (or (= x int) (= y int)) 之类的 if 语句来进行检查,但是......不要认为这是正确的方法去吧。

我是否应该创建一个“添加”程序?有没有其他方法可以做到这一点?在示例中,它们看起来只使用“+”、“-”等。最后;如何检查输入“int”是否为 int,然后将 int 作为输出。

我现在很迷茫,很抱歉我提出了一些含糊不清的问题,但如果有人能帮助我理解这一点,我会非常高兴。

注意:过程 add 接受实数并输出实数,因此它不能很好地遵循示例。但我希望你能理解这个想法。谢谢:)

【问题讨论】:

  • 这里有点不清楚你在问什么。您想使用 Typed Racket 的类型检查机制来实现check,还是想使用 Typed Racket 实现自己的类型检查器?如果是前者,我的猜测是它会很难甚至完全不可行——Typed Racket 不会暴露任何对类型的反射,因为它只一次对整个模块进行类型检查,并且一旦程序完全展开,类型就会被删除。跨度>

标签: scheme racket procedure typed


【解决方案1】:

您提出了一个有趣的问题,但没有简单的答案。

您尝试编写的程序本质上是一个类型检查器。也就是说,它接受一个表达式,并检查给定函数的域是否包含调用它的参数。我们可以写其中一个,但我怀疑你会不满意。来,我现在就去写一篇……

#lang typed/racket

(require typed/rackunit)

;; a type is either
;; - 'number, or
;; - (list 'fn list-of-types type)

;; examples of types
'number
'(fn (number number) number)

(define-type FnTy (List 'fn (Listof Ty) Ty))
(define-type Ty (U 'number FnTy))

;; given an expression, returns a type
;; or signals an error
(: check (Any -> Ty))
(define (check input)
  (cond [(and (list? input)
              (pair? input)
              (symbol? (car input)))
         (define fn-ty (lookup-fn-type (car input)))
         (define arg-types (map check (rest input)))
         (cond [(equal? (cadr fn-ty) arg-types)
                (caddr fn-ty)]
               [else (error 'check
                            "expression didn't type-check: ~v\n"
                            input)])]
        [(number? input)
         'number]
        [else (raise-argument-error
               'check
               "well-formed expression"
               0 input)]))

(: lookup-fn-type (Symbol -> FnTy))
(define (lookup-fn-type fn-name)
  (match fn-name
    ['+ '(fn (number number) number)]
    [other (raise-argument-error 'lookup-fn-type
                                 "known function name"
                                 0 fn-name)]))


(define TEST-INPUT '(+ 3 43))

(check-equal? (check TEST-INPUT)
              'number)
(check-equal? (check '(+ (+ 3 4) 129837))
              'number)

这是否回答了您问题的任何部分?

【讨论】:

    猜你喜欢
    • 2017-06-10
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    • 2012-11-12
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多