我最近开始玩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明星...
由于某种原因不适用于结构类型。为什么会这样?
答案 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
(定义为lvp
或pat
后跟{{ 1}}或其中一个朋友)在不同的地方,而其他人只接受pat
。
为什么会这样?
我想只是...
用于将列表或向量或散列表或其他部分转换为自己的列表,并且没有合理的方法来为固定长度的结构做到这一点。可能值得指出的是pat
对于不同类型的行为有所不同 - 例如,它可以用于提取哈希表中的键列表 - 因此支持结构的唯一原因是if有一个特定的类似操作对结构有意义。我不认为有一个。