可以在 Racket Dispatch: 案例中使用 (range x y) 吗?
Can (range x y) be used in a Racket Dispatch: case?
我想在 case 语句中使用 (range x y)
而不是列出整个范围,这可能吗?
我相信第二个示例中的 (range 1 4)
正在返回一个列表,并且由于 2 != 列表,所以没有匹配项。
> (case 2
[(1 2 3) "matched"]
[else "no match"])
"matched"
> (case 2
[(range 1 4) "matched"]
[else "no match"])
"no match"
这是不可能的,因为 case uses implicit quote. In your example, it quotes all elements in list (range 1 4)
and compares them (using equal?) 与 2.
(case 2
[(range 1 4) "matched"]
[else "no match"])
;2 is compared with 'range, 1, 4 => "no match"
(case 'range
[(range 1 4) "matched"]
[else "no match"])
;'range is compared with 'range, 1, 4 => "matched"
您可以在此处使用 cond:
(let ((v 2))
(cond ((member v (range 1 4)) "matched 1-4")
((member v (range 4 8)) "matched 4-8")
(#true "no match")))
香草 case
将不起作用。 case
每个分支的 LHS 确实仅限于文字。
您可以使用其他形式,例如 cond
或 match
。例如,
(match 2
[-1 'foo]
[0 'bar]
[x #:when (member x (range 1 3)) 'baz]
[x #:when (member x (range 3 5)) 'boo])
这是以效率不如使用 case
为代价的。
另一种方法是编写一个扩展为 case
的宏,例如:
#lang racket
(require syntax/parse/define
(for-syntax racket/list))
(begin-for-syntax
(define-syntax-class range-cls
(pattern (#:range l:number r:number)
#:with result (range (syntax-e #'l) (syntax-e #'r)))))
(define-simple-macro (case-range v [rgs:range-cls rhs ...] ...)
(case v [rgs.result rhs ...] ...))
(case-range 2
[(#:range -1 1) 'foo]
[(#:range 1 3) 'bar]
[(#:range 3 5) 'baz])
我想在 case 语句中使用 (range x y)
而不是列出整个范围,这可能吗?
我相信第二个示例中的 (range 1 4)
正在返回一个列表,并且由于 2 != 列表,所以没有匹配项。
> (case 2
[(1 2 3) "matched"]
[else "no match"])
"matched"
> (case 2
[(range 1 4) "matched"]
[else "no match"])
"no match"
这是不可能的,因为 case uses implicit quote. In your example, it quotes all elements in list (range 1 4)
and compares them (using equal?) 与 2.
(case 2
[(range 1 4) "matched"]
[else "no match"])
;2 is compared with 'range, 1, 4 => "no match"
(case 'range
[(range 1 4) "matched"]
[else "no match"])
;'range is compared with 'range, 1, 4 => "matched"
您可以在此处使用 cond:
(let ((v 2))
(cond ((member v (range 1 4)) "matched 1-4")
((member v (range 4 8)) "matched 4-8")
(#true "no match")))
香草 case
将不起作用。 case
每个分支的 LHS 确实仅限于文字。
您可以使用其他形式,例如 cond
或 match
。例如,
(match 2
[-1 'foo]
[0 'bar]
[x #:when (member x (range 1 3)) 'baz]
[x #:when (member x (range 3 5)) 'boo])
这是以效率不如使用 case
为代价的。
另一种方法是编写一个扩展为 case
的宏,例如:
#lang racket
(require syntax/parse/define
(for-syntax racket/list))
(begin-for-syntax
(define-syntax-class range-cls
(pattern (#:range l:number r:number)
#:with result (range (syntax-e #'l) (syntax-e #'r)))))
(define-simple-macro (case-range v [rgs:range-cls rhs ...] ...)
(case v [rgs.result rhs ...] ...))
(case-range 2
[(#:range -1 1) 'foo]
[(#:range 1 3) 'bar]
[(#:range 3 5) 'baz])