0

我需要在打字/球拍中做矢量叉积。以下代码在#lang racket没有类型注释的情况下可以正常工作。参考

#lang typed/racket

(: cross-product (-> VectorTop VectorTop VectorTop))
(define (cross-product X Y)  
  (: len Integer)
  (define len (vector-length X))
  (for/vector ([n len]) 
    (: ref (-> VectorTop Integer Any))   
    (define (ref V i) (vector-ref V (modulo (+ n i) len)))
    (- (* (ref X 1) (ref Y 2)) (* (ref X 2) (ref Y 1)))))

(define X '#(0 1 0))
(define Y '#(0 0 -1))

(cross-product X Y)

当我使用类型注释运行代码时,会发生类型不匹配错误。

  • 类型检查器:
    预期类型不匹配:
    给出的数字:任何在:(参考 X 1)
  • 类型检查器:
    预期类型不匹配:
    给出的数字:任何在:(参考 Y 2)
  • 类型检查器:
    预期类型不匹配:
    给出的数字:任何在:(参考 X 2)
  • 类型检查器:
    预期类型不匹配:
    给出的数字:任何在:(参考 Y 1)
  • 类型检查器:摘要:在:(
    参考 X 1)
    (参考 Y 2)
    (参考 X 2)
    (参考 Y 1)中遇到 4 个错误

看起来(for/vector ([n len])触发了错误,我尝试将类型注释如(for/vector ([{n: Integer} len]),但最终出现错误:未绑定标识符模块 in n. 我需要纠正什么?有没有更好的方法来做矢量叉积?

4

1 回答 1

2

第一个问题是VectorTop. 这几乎不提供类型信息,因此您应该使用更准确的内容,例如(Vectorof Number). 此外,根据经验,forTyped Racket 中的大多数表单都需要注释。最后,Any也不提供太多类型信息,因此您也应该修复类型ref

更具体地说,您在当前代码中看到的类型错误是由于 ref 函数的类型不准确。但是一旦你解决了这个问题,你就会遇到上面描述的其他问题。

以下代码类型检查。

#lang typed/racket

(: cross-product (-> (Vectorof Number) (Vectorof Number) (Vectorof Number)))
(define (cross-product X Y)
  (define len (vector-length X))
  (for/vector ([n len]) : Number
    (: ref (-> (Vectorof Number) Index Number))   
    (define (ref V i) (vector-ref V (modulo (+ n i) len)))
    (- (* (ref X 1) (ref Y 2)) (* (ref X 2) (ref Y 1)))))

(define X : (Vectorof Number) '#(0 1 0))
(define Y : (Vectorof Number) '#(0 0 -1))

(cross-product X Y)

如果您只想要 R^3 中向量的叉积,请考虑对公式进行硬编码而不是使用 a for,并为 定义一个类型(Vector Real Real Real)。我无法简单地将这个程序转换为使用(Vector Real Real Real).

于 2016-11-21T05:48:28.957 回答