合约:如何接受任何匹配签名的功能?
Contracts: How to Accept Functions of Any Matching Signature?
我正在尝试编写此合同:"accept a function that takes at least one argument, and returns a boolean."
关键是我只关心它 returns 一个布尔值,并且它接受一个或多个参数——例如,它可以是一个接受单个参数的函数,或者一个接受单个参数的函数2 个参数,应接受其中一个。
这是我尝试过的方法:
第一次尝试:
(-> any/c any/c ... boolean?)
第二次尝试:
(->* (any/c)
(any/c ...) ; => syntax error
boolean?)
第三次尝试:
(->* (any/c)
#:rest (listof any/c)
boolean?)
在每一种情况下,合同似乎都希望参数不仅包含在合同规范中,而且要 匹配 它完全正确。也就是说,例如,它 必须 是一个接受任意多个参数而不是 "if it's a function accepting 2 arguments, that's fine because I'm accepting functions that take an arbitrary number of arguments."
的函数
这样的合同怎么写?
这行得通吗?
(define/contract (f x)
(and/c (unconstrained-domain-> boolean?)
(lambda (p)
(let loop ([n (procedure-arity p)])
(match n
[(? number? n) (>= n 1)]
[(arity-at-least n) (>= n 1)]
[(list xs ...) (ormap loop xs)]))))
#t)
我正在尝试编写此合同:"accept a function that takes at least one argument, and returns a boolean."
关键是我只关心它 returns 一个布尔值,并且它接受一个或多个参数——例如,它可以是一个接受单个参数的函数,或者一个接受单个参数的函数2 个参数,应接受其中一个。
这是我尝试过的方法:
第一次尝试:
(-> any/c any/c ... boolean?)
第二次尝试:
(->* (any/c)
(any/c ...) ; => syntax error
boolean?)
第三次尝试:
(->* (any/c)
#:rest (listof any/c)
boolean?)
在每一种情况下,合同似乎都希望参数不仅包含在合同规范中,而且要 匹配 它完全正确。也就是说,例如,它 必须 是一个接受任意多个参数而不是 "if it's a function accepting 2 arguments, that's fine because I'm accepting functions that take an arbitrary number of arguments."
的函数这样的合同怎么写?
这行得通吗?
(define/contract (f x)
(and/c (unconstrained-domain-> boolean?)
(lambda (p)
(let loop ([n (procedure-arity p)])
(match n
[(? number? n) (>= n 1)]
[(arity-at-least n) (>= n 1)]
[(list xs ...) (ormap loop xs)]))))
#t)