gpt4 book ai didi

scheme - Racket /方案: How to avoid repeating function call in cond

转载 作者:行者123 更新时间:2023-12-02 02:21:49 24 4
gpt4 key购买 nike

我几乎为问这个 Racket /方案问题而感到尴尬,但是如果它首先被用来确定“这里”的条件,谁能告诉我如何避免在“那里”内重复函数调用? (条件[这里那里])

我想要得到的相当于 Racket/Scheme 中的以下 C 风格代码(请注意,我只需调用 regex() 一次,因为它存储在变量匹配中):

// initialiation code
if (match = regex("start", "startofstring")) {
list->push(match);
}
else {
printf("No matching regex\n");
}

我想避免的 Racket 代码如下,因为我必须调用 regexp-match 两次:

(cond
[(regexp-match #rx"start" "startofstring")
(set! list (cons (regexp-match #rx"start" "startofstring") list)]
[else
(printf "No matching regex\n")])

现在,我可以这样做:

(define match (regexp-match #rx"start" "startofstring"))
(cond
[match
(set! list (cons match list)]
[else
(printf "No matching regex\n")])

但是这种方法意味着如果我有多个条件,我必须定义很多变量(在我的实际代码中,我有多个条件......但为了上面的代码片段,我只输入之一)。所以它最终会看起来像这样丑陋:

(define match1 (regexp-match #rx"start" "startofstring"))
(define match2 (regexp-match #rx"blah" "startofstring"))
....
(define matchn (regexp-match #rx"blahn" "startofstring"))
(cond
[match1
(set! list (cons match1 list)]
[match2
(set! list (cons match2 list)]
....
[matchn
(set! list (cons matchn list)]
[else
(printf "No matching regex\n")])

我想要的是更多类似的东西:

(cond
[(define match (regexp-match #rx"start" "startofstring"))
(set! list (cons match list)]
[(define match (regexp-match #rx"blah" "startofstring"))
(set! list (cons match list)]
...
[(define match (regexp-match #rx"blahn" "startofstring"))
(set! list (cons match list)]
[else
(printf "No matching regex\n")])

但这显然是一个语法错误,因为 (define .. ..) 不能用在“here”条件中。抱歉,不太清楚……我已尽力传达我所说的内容。我知道这非常简单,但我无法完全理解它(除了 c 风格语言之外,我没有使用过其他语言)。

最佳答案

正确的解决方案是使用cond=>形式:

(cond ((regexp-match #rx"start" "startofstring")
=> (lambda (match)
(set! lst (cons match lst))))
...)

(请注意,我将您的 list 变量重命名为 lst 以避免隐藏内置 list 过程。)

如果你有很多模式,并且多个模式有相同的操作,你应该将公共(public)代码提取到一个单独的过程中:

(define (push! match)
(set! lst (cons match lst)))
(cond ((regexp-match #rx"start" str) => push!)
((regexp-match #rx"blah" str) => push!)
...)
<小时/>

虽然上面的方法有效,但我建议您不要使用 set!,因为它的功能不是很好。从循环构建列表的标准方案方法是使用命名的 let,如下所示:

(let loop ((result '())
(strs strs))
(define (next match)
(loop (cons match result) (cdr strs)))
(if (null? strs)
result
(let ((str (car strs)))
(cond ((regexp-match #rx"start" str) => next)
...)))

关于scheme - Racket /方案: How to avoid repeating function call in cond,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28131556/

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