球拍-递归合同

时间:2019-05-21 21:36:54

标签: racket

我试图为我的二叉树结构建立递归合同:

(struct node (l r)) 
(struct leaf (val))

(define (tree-of val)
    (or/c (struct/c leaf val) (struct/c node (tree-of val) (tree-of val))))

(define/contract (id-tree t)
    (-> (tree-of symbol?) (tree-of symbol?))
    t)

(id-tree (leaf 'a))

尽管我的合同似乎导致了无限循环,但不确定为什么。首先,它是否应该在or / c收到任何正值(在这种情况下来自(struct / c leaf val))之后停止? 即使它检查第二个谓词,(叶'a)显然也不是节点,那么为什么还要递归调用树形树呢?

1 个答案:

答案 0 :(得分:2)

从某种意义上讲,有两个阶段:合同计算和合同检查。您的示例不会在合同计算阶段终止。

假设您将(or/c <a> <b>)附加到值xor/c只是一个普通函数,因此在按值调用(这是Racket拥有的功能)下,将同时计算 <a><b>

如果没有任何问题,<a><b>应分别评估为合同价值vavb。然后,通过针对x测试va来进行合同检查。如果失败,则针对x测试vb

您的示例的问题在于,计算合同价值的过程甚至没有终止。到目前为止,还没有检查。

要完成您想做的事情,请使用flat-rec-contract

(define (tree-of/c val)
  (flat-rec-contract tree-of
                     (struct/c leaf val)
                     (struct/c node tree-of tree-of)))