这里的初学者问题,我只花了几个小时的语言。
球拍有dictionaries,由哈希表,对子列表等实现。(match)
函数识别(hash-table (pat pat)...)
,(list-no-order pat...)
等,但不识别(dict (pat pat)...)
}。
我认为在dict
接口上进行模式匹配会很有用,原因与接口完全相同。它的遗漏表明事实并非如此。谁能告诉我我错过了什么?如果我想对可能是哈希值或列表对的数据使用(match)
,我应该有两个子句吗?别的什么呢?
答案 0 :(得分:0)
我最好的猜测:没有人觉得需要强大到足以为dict
实施match
模式。幸运的是match
是可扩展的。表单define-match-expander
可用于扩展match
可以处理的模式集。
让我们说我们想要
(dict (k0 v0) (k1 v1))
表示与
相同(or (hash-table (k0 v0) (k1 v1)
(list-no-order (cons k0 v0) (cons k1 v1))
(对于具有两个以上键值对的模式类似) 然后我们可以像这样定义一个匹配扩展器:
(define-match-expander dict
(λ (stx)
(syntax-case stx ()
[(_dict (key-pat val-pat) ...)
#'(or (hash-table (key-pat val-pat) ...)
(list-no-order (cons key-pat val-pat) ...))])))
(dict ("a" a) ("b" b) ("c" c))
现在可以理解像match
这样的模式。
一个完整的例子:
#lang racket
(define-match-expander dict
(λ (stx)
(syntax-case stx ()
[(_dict (key-pat val-pat) ...)
#'(or (hash-table (key-pat val-pat) ...)
(list-no-order (cons key-pat val-pat) ...))])))
(define (keys+vals a-dict)
(match a-dict
[(dict ("a" a) ("b" b))
(list a b)]))
(keys+vals (hash "a" 1 "b" 2)) ; gives '(1 2)
(keys+vals '(("b" . 5) ("a" . 4))) ; gives '(4 5)