这个
match
将标识符a
和b
绑定到列表的前缀'(0 1)
和后缀'(3 4 5)
:
(match '(0 1 2 3 4 5)
[`(,a ... 2 ,b ...)
(values a b)])
另一个等价版本:
(match '(0 1 2 3 4 5)
[`(,@(list a ... 2) ,b ...)
(values a b)])
如何将标识符(在模式本身内)绑定到前缀
'(0 1 2)
,包括定界符?
app
模式,它调用一个具有匹配值的函数,然后匹配它返回的值,结合 splitf-at
的版本,在第一个列表而不是第二个列表中包含分区元素,可以是曾经这样做:
; Like splitf-at but includes the element to split at in the first value not the second
(define (splitf-at/inclusive lst pred?)
(let loop ([lst lst]
[first-res '()])
(cond
((empty? lst)
(values (reverse first-res) '()))
((pred? (car lst))
(loop (cdr lst) (cons (car lst) first-res)))
(else
(values (reverse (cons (car lst) first-res)) (cdr lst))))))
; Gives '(0 1 2) '(3 4 5)
(match '(0 1 2 3 4 5)
((? list? (app (lambda (lst) (splitf-at/inclusive lst (negate (curry = 2)))) a b))
(values a b)))
(注意使用
(? list? ...)
来确保值是一个列表,然后再尝试调用任何依赖于它的函数。)
你可以定义一个match extender让它看起来更漂亮:
(define-match-expander split-list
(lambda (stx)
(syntax-case stx (...)
((_ x (... ...) val y (... ...))
#'(? list? (app (lambda (lst) (splitf-at/inclusive lst (lambda (elem) (not (equal? elem val))))) x y))))))
; Also gives '(0 1 2) '(3 4 5)
(match '(0 1 2 3 4 5)
((split-list a ... 2 b ...)
(values a b)))