【问题标题】:When racket will check the struct's type in a function?球拍何时会在函数中检查结构的类型?
【发布时间】:2021-06-10 00:50:51
【问题描述】:

这个程序:

(struct pt (x y))

(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
       (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))

工作正常。如果添加一行:

(struct pt2 (x y))

然后

(distance (pt 0 0) (pt2 3.1415 2.7172))

有错误

pt-x: contract violation
expected: pt?
given: #<pt2>

我认为是因为函数距离使用“pt-x”和“pt-y”来检查结构的类型。在其他静态类型语言中,类型声明和类型检查将发生在函数的头部,如下所示:

(define (distance p1:pt p2:pt)

所以作为球拍,如果有......可能在“(定义(距离p1 p2)”之后有100行代码,并且需要1分钟,那么行“(sqrt(+(sqr(-(pt-x p2) (pt-x p1)))",发现类型错误,会浪费1分钟?

谢谢!

【问题讨论】:

  • 所以如果我使用类型化的球拍,我可以在函数的第一行做静态类型检查吗?

标签: lisp racket


【解决方案1】:

我不确定您所说的“浪费 1 分钟”是什么意思。

  • 从某种意义上说,distance 被调用后,(pt-x p2) 可能需要 1 分钟才能执行?
  • 或者从某种意义上说,整个程序可能需要 1 分钟才能执行 (pt-x p2)

如果您指的是第一个,您可以将合同添加到distance。例如,

#lang racket

(struct pt (x y))

(define/contract (distance p1 p2) (-> pt? pt? number?)
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))

每次调用distance,它都会检查p1p2是否满足pt?,如果检查失败,就会马上报错。请注意,这发生在运行时并且仅在调用 distance 时发生。程序可能运行很长时间没有问题,然后执行(distance (pt2 0 0) (pt2 3.1415 2.7172)),然后才会出现错误。


如果您指的是第二个,那么您根本不希望程序运行以发现错误。也就是说,您希望静态地发现错误。您将需要使用 Typed Racket 或类似的东西。这类似于具有静态类型检查的语言。

#lang typed/racket

(struct pt ([x : Number] [y : Number]))

(: distance : pt pt -> Number)
(define (distance p1 p2) 
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))

【讨论】:

    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多