Data structures 表达式的模式匹配
我希望你能帮我一点忙。作为家庭作业,我应该编写一个函数,用模式匹配检查表达式是否对应于某个结构定义Data structures 表达式的模式匹配,data-structures,pattern-matching,racket,Data Structures,Pattern Matching,Racket,我希望你能帮我一点忙。作为家庭作业,我应该编写一个函数,用模式匹配检查表达式是否对应于某个结构定义 ; Expression -> S-Expression ; converts an expression into the corresponding S-Expression (check-expect (expr->sexpr EXPRESSION-1) '42) (check-expect (expr->sexpr EXPRESSION-2) '(+ 4 (* 5 8))
; Expression -> S-Expression
; converts an expression into the corresponding S-Expression
(check-expect (expr->sexpr EXPRESSION-1) '42)
(check-expect (expr->sexpr EXPRESSION-2) '(+ 4 (* 5 8)))
(check-expect (expr->sexpr EXPRESSION 3) '(/ (- 11 7) 2))
(check-expect (expr->sexpr (make-addition (make-literal 1) (make-literal 2))
'(+ 1 2))
(define (expr->sexpr e)
(match e
[(literal value) 'value]
[(addition lhs rhs) '(+ (addition lhs) (addition rhs))]
[(subtraction lhs rhs) '(- (subtraction lhs) (subtraction rhs))]
[...]
[...]
))
以下是定义:
(define-struct literal (value))
(define-struct addition (lhs rhs))
(define-struct subtraction (lhs rhs))
(define-struct multiplication (lhs rhs))
(define-struct division (lhs rhs))
我的代码如下所示:
; An Expression is one of:
; - (make-literal Number)
; - (make-addition Expression Expression)
; - (make-subtraction Expression Expression)
; - (make-multiplication Expression Expression)
; - (make-division Expression Expression)
; interp. abstract syntax tree of arithmetic expressions
(define EXPRESSION-1 (make-literal 42))
(define EXPRESSION-2
(make-addition (make-literal 4) (make-multiplication (make-literal 5) (make-literal 8))))
(define EXPRESSION-3
(make-division (make-subtraction (make-literal 11) (make-literal 7)) (make-literal 2)))
; Any -> Boolean
; checks whether e is an Expression
(check-expect (expression? EXPRESSION-1) #true)
(check-expect (expression? EXPRESSION-2) #true)
(check-expect (expression? (make-literal "42")) #false)
(define (expression? e)
(match e
[(and (literal?) (number? literal-value)) #true]
[(and (addition?) (number? addition-lhs) (addition-rhs)) #true]
[substraction? #true]
[multiplication? #true]
[division? #true]
[... #false]
))
(define (expression? e)
(match e
[(literal v) (number? v)]
[(or (addition l r) (subtraction l r)
(multiplication l r) (division l r))
(and (expression? l) (expression? r))]
[_ #false]))
我这样做的原因是因为我必须检查表达式是否是scstructure,我还必须确保该结构的元素只不过是数字,因为第二次测试会失败。
但不知何故,我的方法不起作用,因为表达式-1和表达式-2的测试已经失败了,我无法得到我的头Straighth,为什么
我把下面的四行保留在开头,因为我想把重点放在加法行上,因为我希望这是对“加法”行的简单重复。
你将如何着手使之正确?
此外,您是否建议将数字检查作为结构元素外包到单独的功能中
干杯
编辑:
现在,正如我想我已经明白了,我正在努力完成下一个任务,我相信它的工作方式必须与下面阿萨瓦·舒克拉建议的几乎相同。任务是将表达式转换为s表达式,例如,从make addition make literal 1 make literal 2到“+1 2”,也使用模式匹配
; Expression -> S-Expression
; converts an expression into the corresponding S-Expression
(check-expect (expr->sexpr EXPRESSION-1) '42)
(check-expect (expr->sexpr EXPRESSION-2) '(+ 4 (* 5 8)))
(check-expect (expr->sexpr EXPRESSION 3) '(/ (- 11 7) 2))
(check-expect (expr->sexpr (make-addition (make-literal 1) (make-literal 2))
'(+ 1 2))
(define (expr->sexpr e)
(match e
[(literal value) 'value]
[(addition lhs rhs) '(+ (addition lhs) (addition rhs))]
[(subtraction lhs rhs) '(- (subtraction lhs) (subtraction rhs))]
[...]
[...]
))
模式中指定的字段名将绑定到各自的子句中。所以不需要谓词
(define (expression? e)
(match e
[(literal v) (number? v)]
[(addition l r) (and (expression? l) (expression? r))]
[(subtraction l r) (and (expression? l) (expression? r))]
[(multiplication l r) (and (expression? l) (expression? r))]
[(division l r) (and (expression? l) (expression? r))]
[_ #false]))
最后一个子句是通配符,即对RHS的任何值进行求值
第2-5条的相同RHS可抽象如下:
; An Expression is one of:
; - (make-literal Number)
; - (make-addition Expression Expression)
; - (make-subtraction Expression Expression)
; - (make-multiplication Expression Expression)
; - (make-division Expression Expression)
; interp. abstract syntax tree of arithmetic expressions
(define EXPRESSION-1 (make-literal 42))
(define EXPRESSION-2
(make-addition (make-literal 4) (make-multiplication (make-literal 5) (make-literal 8))))
(define EXPRESSION-3
(make-division (make-subtraction (make-literal 11) (make-literal 7)) (make-literal 2)))
; Any -> Boolean
; checks whether e is an Expression
(check-expect (expression? EXPRESSION-1) #true)
(check-expect (expression? EXPRESSION-2) #true)
(check-expect (expression? (make-literal "42")) #false)
(define (expression? e)
(match e
[(and (literal?) (number? literal-value)) #true]
[(and (addition?) (number? addition-lhs) (addition-rhs)) #true]
[substraction? #true]
[multiplication? #true]
[division? #true]
[... #false]
))
(define (expression? e)
(match e
[(literal v) (number? v)]
[(or (addition l r) (subtraction l r)
(multiplication l r) (division l r))
(and (expression? l) (expression? r))]
[_ #false]))
但是,我更喜欢第一个版本,因为它反映了表达式定义
编辑12/1/20:
这与前面的示例类似,但我们在进行时构造列表
(check-expect (compile-expression EXPRESSION-1) 42)
(check-expect (compile-expression EXPRESSION-2) `(+ 4 (* 5 8)))
(check-expect (compile-expression EXPRESSION-3) `(/ (- 11 7) 2))
(define (compile-expression e)
(match e
[(literal v) v]
[(addition l r) (list '+ (compile-expression l) (compile-expression r))]
[(subtraction l r) (list '- (compile-expression l) (compile-expression r))]
[(multiplication l r) (list '* (compile-expression l) (compile-expression r))]
[(division l r) (list '/ (compile-expression l) (compile-expression r))]
[_ (error "Not an Expression")]))
我更喜欢此版本,因为它允许您轻松创建更复杂的结构:
(define (compile-expression e)
(match e
[(literal v) v]
[(addition l r) `(+ ,(compile-expression l) ,(compile-expression r))]
[(subtraction l r) `(- ,(compile-expression l) ,(compile-expression r))]
[(multiplication l r) `(* ,(compile-expression l) ,(compile-expression r))]
[(division l r) `(/ ,(compile-expression l) ,(compile-expression r))]
[_ (error "Not an Expression")]))
您可以了解有关Quote、QUISQUOTE和Unquote的更多信息。一些入门文档:非常感谢您的回复,它帮助我更好地理解模式匹配,并且我还能够创建一个计算实际算术表达式的函数。但现在,正如我所想,我正在努力完成下一个任务,我相信它必须以几乎相同的方式工作。任务是将表达式转换为s表达式,例如,从make addition make literal 1 make literal 2到“+1 2”,也使用模式匹配。我将在另一条评论中发布代码,也许你还有一点提示?