Racket 敲诈-递归契约
我试图为我的二叉树结构创建一个递归契约:Racket 敲诈-递归契约,racket,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
(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)收到)后,它不应该停止吗?
即使它检查第二个谓词,(leaf'a)显然不是一个节点,那么为什么它会再次递归调用tree of 从某种意义上讲,有两个阶段:合同计算和合同检查。您的示例不会在契约计算阶段终止 假设将
(或/c)
附加到值x
或/c
只是一个普通函数,因此在“按值调用”(这是Racket的功能)下,
和
都将被计算
如果没有问题,
和
应分别评估为合同值va
和vb
。然后,合同检查从测试x
和va
开始。如果失败,那么它将针对vb
测试x
您的示例的问题是,计算合同价值的过程甚至没有终止。到那时还没有进行任何检查
要完成您想做的事情,请使用flat rec contract
:
(define (tree-of/c val)
(flat-rec-contract tree-of
(struct/c leaf val)
(struct/c node tree-of tree-of)))
谢谢你的解释,现在有道理了P