Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Racket 敲诈-递归契约_Racket - Fatal编程技术网

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