Racket (或/c#f<;合同>;)vs<;合同>;

Racket (或/c#f<;合同>;)vs<;合同>;,racket,design-by-contract,Racket,Design By Contract,根据《球拍参考手册》中的以下示例,下面的bst/c函数返回一个契约,例如bt中的每个节点都将其值绑定在lo和hi之间 (struct bt (val left right)) (define (bst/c lo hi) (or/c #f (struct/dc bt [val (between/c lo hi)] [left (val) #:lazy (bst lo val)]

根据《球拍参考手册》中的以下示例,下面的
bst/c
函数返回一个契约,例如
bt
中的每个节点都将其值绑定在
lo
hi
之间

(struct bt (val left right))

(define (bst/c lo hi)
  (or/c #f
        (struct/dc bt
                   [val (between/c lo hi)]
                   [left (val) #:lazy (bst lo val)]
                   [right (val) #:lazy (bst val hi)])))
这个定义在我看来很完美,除了一点:这里的
(或/c#f[…])
构造的目的是什么?既然
#f
是一个常数,其计算结果总是为false,为什么不干脆删除
或/c
逻辑,并简单地将
bst/c
定义为:

(define (bst/c lo hi)
  (struct/dc bt
             [val (between/c lo hi)]
             [left (val) #:lazy (bst lo val)]
             [right (val) #:lazy (bst val hi)]))

具有单个值的二元搜索树构造为:

 (bst 42 #f #f)
这里#f用于表示左子树和右子树为空


因为我们希望左、右子树也是二进制搜索树,所以我们需要将值#f作为一个法律bst。合同(或/c#f…)就是这么说的。

啊,谢谢你的解释;现在它有了完美的解释。顺便说一句,您也可能通常将
(或/c#f…+)
视为返回
#f
失败的函数的返回值的契约(而不是通过引发异常或使用
可能
-ish
结构或其他方式失败)。另一种变体是使用
'some-symbol-表示故障
而不是
#f