在球拍中,我编写了这段基本代码。但是球拍似乎不喜欢第一个子句-尝试运行此子句,我得到错误“ match:模式语法错误:(-3 9)”
(define/match (prob i)
[((- 3 9)) 0]
[(_) 4]
)
奇怪的是,如果我不是使用减法程序,而是使用“列表”程序(即((list 3 9))而不是((-3 9))),则代码可以正常工作。有什么作用?
答案 0 :(得分:1)
如果您的目标是检查参数i
是否等于(-3 9)解析出的值,则问题是Racket match
形式不接受任意表达式作为模式。有关match
表单可以使用哪种模式的更多信息,请查看Pattern Matching上的Racket文档(如您所见,您可能会注意到(list ...)
包含在允许的模式中) !)。但是,简单的答案(如Alex Knauth所说)是将(- 3 9)
替换为(== (- 3 9))
。
另一方面,如果您的目标是检查提供给(prob i)
的自变量是否实际上是表达式(-3 9),则不管其计算结果如何,define/match
都不会满足。球拍功能为pass by value。因此,当有人将表达式作为参数i
传递到您的prob
函数时,i
等于该表达式的求值结果,即
(define (some-function some-argument)
some-argument) ; we just get the number 3 for some-argument
; and have no way of knowing via this function
; that someone actually passed us the expression
; (- (- 9 1) 5)
(some-function (- (- 9 1) 5))
我们将不得不使用称为macro的其他工具。在对符号求值之前,宏会对程序的文本进行操作。您的(prob i)
函数的宏实现将在REPL上像这样工作:
> (define-syntax-rule (prob i)
(if (equal? 'i '(- 3 9))
0
4))
> (prob (- 3 9))
0
> (prob -6)
4
> (prob 78)
4
这称为“语法规则”。它引用了参数i
,然后将其与带引号的表达式(- 3 9)
进行比较,以查看是否以i
的形式提供。让我知道您是否还有任何问题!祝你好运!