pattern-matching - 如何将哈希表与局部变量的值进行匹配?

标签 pattern-matching racket

> (define h #hash((a . 11) (b . 0)))
> (define (f h key)
    (match h
      [(hash-table (key value)) value]
      [_ 'do-something-else]))
> (f h 'a)
'do-something-else  ;; expect 11

我应该如何修改 match 模式,以便上面的函数返回与 (hash-ref h key 'do-something-else) 相同的结果?

一个问题似乎是 match 会自动引用 key,因此它实际上匹配 'key 而不是匹配的值key 局部变量。第二个问题是 match hash-table 似乎想要匹配整个哈希表,而不仅仅是一个键值对。

最佳答案

如何复制hash-ref的行为

要复制 hash-ref 的行为,您需要做两件事:

(1) 使用 key 模式,仅匹配与参数 key 的值等于的内容。您可以使用 == pattern 来执行此操作:

(hash-table ((== key) value))

(2) 匹配除 key 之外还有其他条目的哈希表。您可以通过添加 _ ... 来匹配其他条目来完成此操作。

(hash-table ((== key) value) _ ...)

在上下文中:

(define (f h key)
  (match h
    [(hash-table ((== key) value) _ ...) value]
    [_ 'do-something-else]))

使 (f h key) 的行为类似于 (hash-ref h key 'do-something-else)

为什么你的第一次尝试没有成功

你的模式:

(hash-table (key value))

是否自动引用key,以便它与'key字面匹配。相反,它匹配任何只有一个条目的哈希表:

> (match (hash 'anything-goes 11)
    [(hash-table (key value)) value]
    [_ 'do-something-else])
11

这是因为 key 被解释为模式,而标识符作为模式可以匹配任何内容。如果将其命名为其他名称并在正文中使用它,您可以更清楚地看到这一点:

> (define (f h key-arg)
    (match h
      [(hash-table (key-pat value))
       (printf "key-arg = ~v\n" key-arg)
       (printf "key-pat = ~v\n" key-pat)
       value]))
> (f (hash 'anything-goes 11) 'a)
key-arg = 'a
key-pat = 'anything-goes
11

当您编写的标识符模式“碰巧”与局部变量同名时,它会隐藏它,就像这个示例一样:

> (let ([x "local variable"])
    (match (list 1 2 3)
      [(list 1 2 x)
       x]))
 3

模式中的 x 匹配任何内容,因此它与 3 匹配。该模式遮蔽了 x,因此当正文使用 x 时,它引用的是 3,而不是局部变量。由于这种阴影,局部变量从未被实际使用过。

关于pattern-matching - 如何将哈希表与局部变量的值进行匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52250601/

相关文章:

scheme - 建立一个包含相同 n 项的列表

algorithm - 寻找点集子集的好算法

Scala 多类型模式匹配

scheme - 字符串拆分功能

recursion - 递归地编码近似序列。 DrRacket,方案

recursion - 为什么这在 DrRacket 中有效,但在控制台的 Racket 中无效

racket - 如何在当前 Racket 文件中包含另一个定义文件?

hashmap - 模式匹配选项时引用具有不兼容类型的匹配臂时抛出错误

Scala 任一模式匹配

f# - 检查几种选项类型,然后转换为类型