проверка и сравнение двух контрактов Racket? - PullRequest
0 голосов
/ 02 января 2019

Есть ли способ сравнить их?Это не работает, например:

(equal? (flat-contract integer?) (flat-contract integer?))

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Для определенных видов договоров вы можете использовать contract-equivalent?:

> (contract-equivalent? (flat-contract integer?) (flat-contract integer?))
#true
> (contract-equivalent? (and/c integer? positive?) (and/c integer? positive?))
#true
> (contract-equivalent? (or/c integer? string?) (or/c string? integer?))
#true

Возвращает #true, когда система договоров может доказать, что они эквивалентны.

Однако, как отмечается в документации, результат #false не означает, что они не эквивалентны, он просто означает, что он не знает:

Эта функция консервативна, поэтому может возвращать #false, когда c1 фактически принимает тот же набор значений, что и c2.

> (contract-equivalent? integer? integer?)
#true
> (contract-equivalent? (lambda (x) (integer? x))
                        (lambda (x) (integer? x)))
#false
0 голосов
/ 02 января 2019
  1. Прежде всего, обратите внимание, что функция flat-contract предназначена для обратной совместимости, поэтому вам, вероятно, не следует ее использовать.Из документации:

    Эта функция является пережитком до того, как предикаты могли использоваться непосредственно в качестве фиксированных контрактов.Он существует сегодня для обратной совместимости.

  2. Таким образом, ваш вопрос действительно состоит в том, чтобы спросить, являются ли два предиката одинаковыми или нет.В общем, эта проблема неразрешима из-за проблемы остановки .Тем не менее, для вашей цели, вы можете избежать референтного равенства.

    > ;; both are in the same memory address
      (eq? integer? integer?) 
    #t
    > ;; obviously not in the same memory address
      (eq? integer? real?)
    #f
    

    Пожалуйста, обратите внимание на его предостережение

    > ;; although they look the same syntactically, 
      ;; the function objects are in different memory address
      (eq? (lambda (x) x) (lambda (x) x))
    #f
    > (define x (lambda (x) x))
    > (define y x)
    > ;; both are in the same memory address
      (eq? x y)
    #t
    > ;; flat-contract creates a function in a new memory address
      (eq? (flat-contract integer?) (flat-contract integer?))
    #f
    
...