gpt4 book ai didi

types - 什么时候 ->i 在 Racket 中真的有用?

转载 作者:行者123 更新时间:2023-12-04 00:58:15 24 4
gpt4 key购买 nike

我一直在经历Contracts in the Racket Guide .
->i构造允许对函数的输入/输出施加任意约束。

例如,我可以有一个 unzip函数接受一对列表并返回两个列表。使用契约,我可以确认 in-list 的每个元素都是一对,并且 out-lists 具有相应的元素。

Racket 指南暗示这是契约(Contract)有用的时候。但这似乎在函数本身内部完成会更好。如果遇到非对,我可能会抛出错误,这将检查 in-list。通过具有正确的功能自动检查输出。

通过比简单类型更复杂的契约以某种方式改进代码的具体示例是什么?

最佳答案

正如您所描述的,几乎可以在 ->i 中执行的任何检查。可以在函数本身内执行,但同样,合约执行的任何检查在大多数情况下都可以在函数本身内执行。将信息编码到契约(Contract)中提供了一些优势。

  • 您可以从函数实现中提取不变量。这很好,因为您不需要用保护子句来混淆函数本身,您只需编写代码并知道不变量将由合约维护。
  • 合约努力提供良好的错误报告。他们会自动将“责任”分配给违反契约(Contract)的一方,对于复杂的契约(Contract),他们会在错误消息中添加上下文,以尽可能清楚地说明问题是什么。

  • 这些在 ->i 中最为明显当合约需要在提供给函数的参数中指定依赖项时。例如,我有一个收藏库,其中包括一个 subsequence功能。它需要三个参数,一个序列、一个开始索引和一个结束索引。这是我用来保护它的契约(Contract):
    (->i ([seq sequence?]
    [start exact-nonnegative-integer?]
    [end (start) (and/c exact-nonnegative-integer? (>=/c start))])
    [result sequence?])

    这允许我明确指定结束索引必须大于或等于开始索引,并且我不必担心在我的函数中检查该不变量。当我违反此契约(Contract)时,会收到一条很好的错误消息:
    > (subsequence '() 2 1)
    subsequence: contract violation
    expected: (and/c exact-nonnegative-integer? (>=/c 2))
    given: 1
    which isn't: (>=/c 2)

    它也可用于确保更复杂的不变量。我也定义了我自己的 map功能,就像 Racket 内置的 map , 支持可变数量的参数。提供给 map 的程序必须接受与提供的序列相同数量的参数。我将以下契约(Contract)用于 map :
    (->i ([proc (seqs) (and/c (procedure-arity-includes/c (length seqs))
    (unconstrained-domain-> any/c))])
    #:rest [seqs (non-empty-listof sequence?)]
    [result sequence?])

    这份契约(Contract)保证了两件事。首先, proc如上所述,argument 必须接受与序列相同数量的参数。此外,它还要求该函数始终返回单个值,因为 Racket 函数可以返回多个值。

    在函数体内检查这些不变量要困难得多,因为,尤其是对于第二个不变量,它们必须延迟到函数本身被应用为止。还必须在每次调用函数时检查它。另一方面,契约包装函数并自动处理它。

    您是否总是想将函数的每个不变量编码到合约中?可能不是。但是如果你想要额外的控制级别, ->i可用。

    关于types - 什么时候 ->i 在 Racket 中真的有用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30465117/

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