首页 > 解决方案 > 类型化 Racket 中的 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?)

标签: rackettyped-racket

解决方案


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

#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 Racketrequire/typed看到#:opaque时,它仍然需要将您提供的谓词graph?视为无类型代码。但它还需要使用来自无类型代码的谓词来保护类型无类型边界上的值。graph?谓词具有 type ,因此当类型化的球拍使用(-> Any Boolean)类型化代码中的值调用它时,它会使用 type 传递它Any。但是,如果在此之前它有一个更具体的类型,涉及必须输入的输入,它仍然需要防止无类型代码以错误的方式“使用它”,或者提供错误的无类型输入。

添加一个不透明的结构通过创建一个graph?不需要以相同方式“查看内部”值的新谓词来回避这一点。


推荐阅读