gpt4 book ai didi

racket - 为什么不能在 # :fallbacks refer to the generic methods? 中编码

转载 作者:行者123 更新时间:2023-12-04 15:54:46 28 4
gpt4 key购买 nike

这段代码:

(require racket/generic)

;; A holder that assigns ids to the things it holds. Some callers want to know the
;; the id that was assigned when adding a thing to the holder, and others don't.
(define-generics holder
(add-new-thing+id holder new-thing) ;returns: holder id (two values)
(add-new-thing holder new-thing) ;returns: holder
#:fallbacks
[(define (add-new-thing holder new-thing) ;probably same code for all holder structs
(let-values ([(holder _) (add-new-thing+id holder new-thing)])
holder))])

产生这个错误信息:

add-new-thing+id: method not implemented in: (add-new-thing+id holder new-thing)

我可以通过在后备中添加 define/generic 来修复它,如下所示:

  #:fallbacks
[(define/generic add add-new-thing+id)
(define (add-new-thing holder new-thing)
(let-values ([(holder _) (add holder new-thing)])
holder))])

但这似乎增加了复杂性而没有增加值(value),我不明白为什么一个有效而另一个无效。

据我了解#:fallbacks,这个想法是泛型定义可以从最原始的方法中构建方法,因此实现泛型接口(interface)的结构并不总是需要重新实现相同的一大组方法,通常只是用相同的代码调用核心方法——但如果需要,它们可以覆盖那些“派生”方法。说,为了优化。这是一个非常有用的东西*——但我是否误解了回退?

回退代码无法引用通用方法似乎很奇怪。回退的主要值(value)不是调用它们吗? define/generic 的文档说在结构定义中的 #:methods 子句之外调用它是一个语法错误,所以我可能误用了它。无论如何,有人可以解释一下 #:fallbacks 子句中代码的规则是什么吗?你应该怎么写?

* Clojure 世界有类似的东西,在 potemkin 中库的 def-abstract-typedeftype+,但没有很好地集成到语言中。 potemkin/def-map-type 很好地说明了为什么 fallbacks(无论如何,据我所知)是如此有值(value)的特性。

最佳答案

您的代码的第二个版本是正确的。

如果您有 add-new-thing+id 的回退定义,那么您的代码的第一个版本将起作用,但是因为您指的是回退范围之外该方法的任何可能定义,您需要将其导入。


不得不在后备子句中再次定义泛型实际上感觉有点重复。这是因为 #:fallbacks#:methods 的工作方式相同,因此具有使用自己的定义覆盖泛型的相同行为。

要明确表示您正在重写一个方法,您需要使用 define/generic(实际上并没有定义任何东西)“导入”它到您的子句中,它只是将泛型导入到上下文中)。

作为documentation对于 define/generic 说:

When used inside the method definitions associated with the #:methods keyword, binds local-id to the generic for method-id. This form is useful for method specializations to use generic methods (as opposed to the local specialization) on other values.

然后在 define-generics 中:

The syntax of the fallback-impls is the same as the methods provided for the #:methods keyword for struct.

这意味着 #:fallbacks 与在结构中使用 #:methods 具有相同的行为。

为什么?

该行为背后的逻辑是方法定义 block ,如 #:methods#:fallbacks 可以访问它们自己的所有泛型定义,因此它是很容易引用你自己的上下文。要从此上下文之外显式使用泛型,您需要使用 define/generic

关于racket - 为什么不能在 # :fallbacks refer to the generic methods? 中编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52287226/

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