Typed Racket中的Racket通用图库

3

我试图在Typed Racket中使用通用图形库,通过使用require/typed导入它,但是我一直收到这些奇怪的长错误。是否有人成功地使类型检查器与通用图形库合作?

#lang typed/racket

(require/typed graph
               [#:opaque Graph graph?]
               [unweighted-graph/undirected ((Listof (List Any Any)) -> Graph)]
               [add-edge! (Graph Any Any -> Void)])

(define g : Graph (unweighted-graph/undirected '((1 2) (1 3))))
(add-edge! g 2 3)

graph?: contract violation
  any-wrap/c: Unable to protect opaque value passed as `Any`
  value: #<unweighted-graph>
  This warning will become an error in a future release.
  in: the 1st argument of
      a part of the or/c of
      (or/c
       struct-predicate-procedure?/c
       (-> Any boolean?))
  contract from: (interface for graph?)

你是指 import/typed 还是 require/typed?我相当确定你是指后者,但这可能是问题的原因? - Lazerbeak12345
糟糕!我一直在使用require/typed,而import是我的笔误。但这并没有引起任何问题。 - Alex MacLean
1个回答

4

这并不理想,但可以有一个解决方法:

#lang typed/racket

(module wrapper racket
  (provide graph? unweighted-graph/undirected add-edge!)
  (require (prefix-in g: graph))
  (struct graph [g]) ; struct generates the predicate
  (define (unweighted-graph/undirected es) ; wrap output graph
    (graph (g:unweighted-graph/undirected es)))
  (define (add-edge! g a b) ; unwrap input graph
    (g:add-edge! (graph-g g) a b)))

(require/typed 'wrapper
               [#:opaque Graph graph?]
               [unweighted-graph/undirected ((Listof (List Any Any)) -> Graph)]
               [add-edge! (Graph Any Any -> Void)])

(define g : Graph (unweighted-graph/undirected '((1 2) (1 3))))
(add-edge! g 2 3)

当 Typed Racket 的 `require/typed` 命令看到 `#:opaque` 时,它仍然需要将您提供的谓词 `graph?` 视为未加类型注释的代码。但是它还需要使用该谓词来保护从类型和非类型之间的边界传递的值。`graph?` 谓词的类型为 `(-> Any Boolean)`,因此当 Typed Racket 用来自已加类型注释代码的值调用它时,它会传递类型为 `Any` 的值。但是,如果在此之前它具有包含必须加类型注释的输入的更具体类型,它仍然需要防止未加类型注释的代码以错误的方式“使用”它或提供不良的未加类型注释的输入。
通过添加一个不透明结构体可以避免这种情况,因为它创建了一个新的 `graph?` 谓词,它不需要以同样的方式“查看”值的内部。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接