为什么在(匹配)中没有(dict(k v)...)模式?

问题描述:

初学者问题在这里,我只花了几个小时的语言。为什么在(匹配)中没有(dict(k v)...)模式?

球拍dictionaries,通过哈希表来实现,对列表等的(match)功能识别(hash-table (pat pat)...)(list-no-order pat...)等,但不(dict (pat pat)...)

我认为这对于dict接口上的模式匹配会有帮助,因为有相同的理由,它有用的接口。其疏忽表明情况并非如此。谁能告诉我我错过了什么?如果我想使用(match)上的数据可能是哈希或成对列表,我应该有两个子句?完全是另一件事?

我最好的猜测是:没有人觉得需要足够强大的实施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)) WIL我可以理解为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)