如何使用键入 scheme/racket

How to use typed scheme/racket

我正在尝试学习打字 scheme/racket(?)。下面是我的代码中的示例:

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

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

(check '(+ int int))

应该导致

int

但是

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

结果应该是这样的:

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

即check应该取一个list。

问题:

如何实施 "check"?首先,我通过 "ok, I have a list, so let's use car and cdr" 获取运算符和操作数,但它不起作用,我什至不知道为什么它不起作用。我也虽然关于制作 if 语句,如 (if (and (= xy) (or (= x int) (= y int)) 等等来进行检查但是......不认为这是正确的方法去吧。

要不要做程序"add"?还有其他方法吗?在示例中,看起来他们只使用“+”、“-”等。最后;如何检查输入 "int" 是否为 int,然后将 int 作为输出。

我现在很迷茫,很抱歉我的问题很含糊,但如果有人能帮助我理解这一点,我会很高兴。

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

你在问一个有趣的问题,而且没有简单的答案。

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

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

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