如何用匹配项替换if语句,使代码更易于阅读和理解?
(: f (t1 -> integer))
(define f
(lambda (x)
(if (natural? (t1-b x))
(+ (t1-a x)
(t1-b x)
(t1-c x))
(if (and (= (t2-e (t1-b x)) 1)
(= (t2-d (t1-b x)) 1))
10
(- (+ (t2-d (t1-b x))
(t2-e (t1-b x)))
(t1-a x))))))
答案 0 :(得分:1)
这不是match
的好用例,因为条件不适合用于模式匹配。但是我们可以使用cond
简化嵌套条件:
(define (f x)
(cond ((natural? (t1-b x))
(+ (t1-a x)
(t1-b x)
(t1-c x)))
((and (= (t2-e (t1-b x)) 1)
(= (t2-d (t1-b x)) 1))
10)
(else
(- (+ (t2-d (t1-b x))
(t2-e (t1-b x)))
(t1-a x)))))
答案 1 :(得分:0)
您没有提供t1
或t2
的结构定义,所以我会猜测。
(struct t1 [a b c] #:transparent)
(struct t2 [d e] #:transparent)
假设这些定义与您的定义相符,我可以翻译每个分支问题和答案。
?
模式的条件,命名为消除选择器第一个分支条件(natural? (t1-b x))
可以转换为
(t1 _ (? natural?) _)
?
模式将谓词应用于与其匹配的值,并且仅在谓词返回true时才匹配。要查找其文档,请在match documentation中搜索(? expr pat ...)
。
而且,由于在分支答案中使用了选择器t1-a
,t1-b
和t1-c
,因此可以命名它们
(t1 a (? natural? b) c)
整个分支看起来像
[(t1 a (? natural? b) c)
(+ a b c)]
1
第二个分支条件
(and (= (t2-e (t1-b x)) 1)
(= (t2-d (t1-b x)) 1))
可以翻译为
(t1 _ (t2 1 1) _)
而且,由于您在分支答案中未使用任何选择器,因此无助于命名通配符,并且整个问题答案对都可以翻译为
[(t1 _ (t2 1 1) _)
10]
对于这个,没有分支问题,但是主体中使用了选择器:
(- (+ (t2-d (t1-b x))
(t2-e (t1-b x)))
(t1-a x))))
首先在t1
上删除x
的选择器:
[(t1 a b _)
(- (+ (t2-d b)
(t2-e b))
a)]
然后在t2
上删除b
的选择器:
[(t1 a (t2 d e) _)
(- (+ d e)
a)]
将三个分支放在正文中的(match x branch1 branch2 ...)
; assuming these struct definitions
(struct t1 [a b c] #:transparent)
(struct t2 [d e] #:transparent)
(: f (t1 -> integer))
(define f
(lambda (x)
(match x
[(t1 a (? natural? b) c)
(+ a b c)]
[(t1 _ (t2 1 1) _)
10]
[(t1 a (t2 d e) _)
(- (+ d e)
a)])))