gpt4 book ai didi

racket - 使用合约定义 Typed Racket 结构

转载 作者:行者123 更新时间:2023-12-05 05:17:18 34 4
gpt4 key购买 nike

有没有一种方法可以在 Typed Racket 中为整个结构定义一个(类型化的)结构?在我的特定情况下,我有一个将两个列表作为字段的结构,我希望这两个列表的长度相同。

我看过:

  • make-struct-type ,它允许规范构造函数调用的“守卫”。如果长度不匹配,我可以传递一个引发异常的过程,但我不知道如何处理 make-struct-type 返回的值。
  • struct/ccontract-outstruct 形式,两者都从各个领域的契约(Contract)中产生结构契约(Contract)。这在这里似乎没有帮助。

理想情况下,我想立即将契约(Contract)绑定(bind)到结构(如 define/contract 中),但是当我提供类型的程序。但是,我目前单独提供识别器和访问器过程,而不是使用 struct-out(这样我可以排除或重命名各个过程),我想保持这种灵 active 。

现在我有这样的东西:

(provide
(rename-out
[MyStruct my-struct]
[MyStruct? my-struct?]
[MyStruct-foo my-struct-foo]
[MyStruct-bar my-struct-bar]
)
)

(struct MyStruct (
[foo : (Listof Symbol)]
[bar : (Listof Any)]
))

最佳答案

哇。我很惊讶在 Typed Racket 中做到这一点有多么困难。在普通的(无类型的)Racket 中,它就像添加一个 #:guard 一样简单,让你成为 struct。 .不幸的是,struct Typed Racket 中的表单不支持它。

因此,为了解决这个问题,我将生成一个具有私有(private)(对于模块)构造函数名称的结构类型,然后创建您自己的构造函数,该函数实际上执行您希望它检查的契约。

这最终看起来像这样:

(struct env ([keys : (Listof Symbol)]
[values : (Listof Any)])
#:constructor-name internal-env)

(: make-env (-> (Listof Symbol) (Listof Any) env))
(define (make-env k v)
(unless (= (length k) (length v))
(raise-arguments-error 'env
"env key and value counts don't match"
"keys" k
"values" v))
(internal-env k v))

现在,当您提供结构时,只需不提供 internal-env,而是提供 make-env 函数:

(provide (except-out (struct-out env)
internal-env)
make-env)

现在,当我构造一个环境时,我得到一个(动态)检查以确保列表长度匹配:

> (make-env '() '())
#<env>
> (make-env '(a) '(1))
#<env>
> (make-env '(a) '())
env: env key and value counts don't match
keys: '(a)
values: '()

关于racket - 使用合约定义 Typed Racket 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49415146/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com