racket - 确定以编程方式定义哪些函数

标签 racket

我想将对特定函数集的调用替换为我的实现(如果可用),例如:

(define (call-my-fn f . args)
  (cond [(eq? f append) (apply my-append args)]))

我的所有实现都在一个单独的文件中,我不想继续添加到 cond 子句。有没有办法我可以写这样的东西:

(require "my-fns.rkt")
(define (call-my-fn f . args)
  (cond [(is-defined? f "my-fns.rkt") (apply "my-version-of-f" args)]))

最佳答案

dynamic-require可用于动态查询其他模块中提供的变量。 dynamic-require 的第三个参数控制当查询的变量不存在时应该发生的情况,因此您可以执行以下操作:

;; lib.rkt

#lang racket

(provide foo bar)
(define foo #f)
(define (bar x) x)
;; client.rkt

#lang racket

(define does-not-exist (gensym))
(eq? (dynamic-require "lib.rkt" 'foo (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'bar (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'baz (λ () does-not-exist)) does-not-exist) ; #f

人们可能会尝试将上面的内容简化为

;; client.rkt

#lang racket

(dynamic-require "lib.rkt" 'foo (λ () #f)) ; #f
(dynamic-require "lib.rkt" 'bar (λ () #f)) ; #<procedure:bar>
(dynamic-require "lib.rkt" 'baz (λ () #f)) ; #f

如果您知道所有提供的标识符均未绑定(bind)到 #f,则此方法可行。但如果情况并非如此,则会给出错误的结果,如上所示。该解决方案通过返回一个新的唯一符号 does-not-exist 来解决该问题,该符号本身只是 eq? 。然后,我们可以使用eq?来测试返回值是否为does-not-exist。如果是,那么我们可以确定未提供标识符。

关于racket - 确定以编程方式定义哪些函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63085739/

相关文章:

scheme - 为什么延续没有有用的数量?

scheme - 寻找更清晰的方法来从数字列表中创建关联列表

algorithm - 编写一个程序来测试给定数字是否是 Scheme 中不同平方的和

LISP 1.5 lisp 与机器语言有何相似之处?

plugins - 如何构建 Sublime Text 2 插件来编译 Racket (方案)代码?

plot - 如何使用 Racket 绘制 3 维图形

racket - Define 相对于 Let 的优点

boolean - 如何将产生 boolean 值的 cond 语句转换为仅涉及 not、and 和 or 的表达式

scheme - Racket 中的管道

mapping - 方案:映射 let 和 set!上 list