在PL Racket中使用与用户定义类型的匹配

时间:2015-05-12 21:42:01

标签: racket

以下PL代码在#lang pl下无效:

根据Alexis Kings的回答编辑代码

(define-type BINTREE
  [Leaf Number]
  [Node BINTREE BINTREE])

(: retrieve-leaf : BINTREE -> Number)
(define (retrieve-leaf btree)
  (match btree
  [(Leaf number) number])

我想要达到的目的如下:

  1. 收到BINTREE作为输入
  2. 检查树是否只是一片叶子
  3. 返回叶子数值
  4. 这可能是一个基本问题,但我该如何解决这个问题呢?

    编辑:如果使用cases代替match,上述内容似乎有效。 那是为什么?

2 个答案:

答案 0 :(得分:2)

正如您所发现的,matchcases是两个相似但又分开的 的东西。第一个用于一般的Racket值,第二个用于 用于您使用define-type定义的内容。不幸, 它们在任何一个方向都不能很好地混合,所以如果你有一个明确的类型 然后你需要使用cases

至于原因,它有点复杂......有一点是 在pl足够强大之前,match语言已经很好了 方便地处理任意值。它现在,但它不能 很容易调整以完成案例:define-type背后的想法 是通过强制使用只是来简化编程 这些值的cases ---没有字段访问器,没有谓词 对于变体(仅适用于整个类型),当然没有变异。 尽管如此,只需cases就可以做任何你需要的事情。如果你 阅读,核心思想是模仿HM中不相交的联合类型 ML和Haskell等语言,只有cases模式匹配 可用,许多功能都很容易启动,因为只有一种方式 处理它们。

match和Typed Racket更接近能够做这些事情, 但它仍然没有足够的力量去做所有这些 - 就是这样 为什么cases在不久的将来会与match分开。

作为旁注,这与我想要的相反 - 我知道这一点 往往是一个混乱的点,所以我喜欢只使用match 始终。也许我会在某个时候打破并破坏事情 cases也称为match,分支的内容也会 用于猜测您是否真的需要真实的matchcases 版。但这确实是一个粗暴的黑客行为。

答案 1 :(得分:1)

I think you're on the right track, but your CREATE TABLE `poll_votes` ( `poll_id` int(11) NOT NULL, `voter_id` int(11) NOT NULL, `poll_option_id` int(11) NOT NULL, PRIMARY KEY (`poll_id`,`voter_id`), KEY `fk_poll_votes_polls1_idx` (`poll_id`), KEY `fk_poll_votes_poll_votes1_idx` (`poll_option_id`), KEY `fk_poll_votes_users1_idx` (`voter_id`), CONSTRAINT `fk_poll_votes_polls1` FOREIGN KEY (`poll_id`) REFERENCES `polls` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT `fk_poll_votes_poll_options1` FOREIGN KEY (`poll_option_id`) REFERENCES `poll_options` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT `fk_poll_votes_users1` FOREIGN KEY (`voter_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION ) syntax isn't correct. It should look like this:

match

The match pattern clauses must be inside the (: retrieve-leaf : BINTREE -> Number) (define (retrieve-leaf btree) (match btree [(Leaf number) number])) form. Additionally, match is just a binding, not a procedure, so it doesn't need to be in parens.