如何使用打字方案/球拍

问题描述 投票:0回答:1

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

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

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

(check '(+ int int))

应该导致

int

但是

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

应该会产生这样的结果:

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

也就是说,check 应该拿一个清单。

问题:

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

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

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

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

racket typechecking typed-racket
1个回答
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)

这能回答您问题的任何部分吗?

© www.soinside.com 2019 - 2024. All rights reserved.