在Racket结构类型上与Kleene星形匹配

时间:2011-11-18 12:30:04

标签: scheme racket

我最近开始玩Racket模式匹配系统,遇到了一个我无法理解的问题。

如果我这样做:

(match (list 1 2 3 4 5 6 7 8 9 10 11 12)
    [(list _ x y z ...) (list y ': x)]) 

在REPL中我得到了

'(3 : 2)

作为我想要的结果。

如果我这样做:

(match (current-date)
    [(date* _ x y z ...) (list y ': x)])

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
    [(date* _ x y z ...) (list y ': x)])

我收到此错误:

match: wrong number for fields for structure date*: expected 12 but got 5 in: (_ x y z ...)

我怀疑Kleene明星...由于某种原因不适用于结构类型。为什么会这样?

2 个答案:

答案 0 :(得分:10)

您真正想要做的是匹配结构中字段的子集,而不是实际将结构中的其余字段绑定到(z ...)。在这种情况下,您可能希望尝试使用struct*匹配模式。

以下是一个例子:

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
   [(struct* date ([minute x] [hour y])) (list y ': x)])

答案 1 :(得分:8)

  

我怀疑Kleene明星...由于某种原因不适用于结构类型。

正确。 ...符号以及相关的..k_____k符号实际上不是匹配的一般功能,而是{{1}的特定功能} -matching和list - 匹配等等。如果您检查the documentation中的正式制作,您会看到某些类型的子模式接受hash-table(定义为lvppat后跟{{ 1}}或其中一个朋友)在不同的地方,而其他人只接受pat

  

为什么会这样?

我想只是...用于将列表或向量或散列表或其他部分转换为自己的列表,并且没有合理的方法来为固定长度的结构做到这一点。可能值得指出的是pat对于不同类型的行为有所不同 - 例如,它可以用于提取哈希表中的键列表 - 因此支持结构的唯一原因是if有一个特定的类似操作对结构有意义。我不认为有一个。