我希望能够写出这样的函数:
print_multiple_times (Int(> 3 && <= 40) foo; String(match "^.{5}$") bar) =
print(bar * foo)
表现如下:
print_multiple_times (Int foo; String bar) =
if not (foo > 3 && foo <= 40):
throw InputError('print_multiple_times, 'foo)
if not (bar match "^.{5}$"):
throw InputError('print_multiple_times, 'bar)
print(bar * foo)
答案 0 :(得分:1)
以下是Racket's合同系统的示例:
(define/contract (log10 x)
(-> (>/c 0) real?)
(/ (log x) (log 10)))
上面代码中的合同就是这一行:(-> (>/c 0) real?)
。箭头表示函数契约,其中包含参数合约,后跟单个合同。参数上的契约是(>/c 0)
,它检查参数是否大于零的实数。结果的合同是real?
,这是Racket内置的实数谓词。谓词可以在需要合同的任何地方使用。此外,正则表达式充当接受它匹配的字符串的契约。 Racket拥有丰富的库,可用于制作各种合同。
以下是使用该功能的一些很好的例子:
> (log10 10)
1.0
> (log10 250)
2.397940008672037
这是合同违规的一个例子:
> (log10 -5.0)
; log10: contract violation
; expected: a number strictly greater than 0
; given: -5.0
; in: the 1st argument of
; (-> (>/c 0) real?)
; contract from: (function log10)
; ....
有关详细信息,请参阅the chapter on contracts in the Racket Guide。
IIRC,Racket的合同系统部分受到了Eiffel的启发,但我认为Racket的合同更具表现力,并且Eiffel合同因子类化而被打破。答案 1 :(得分:0)
在提供隐式转换/类型转换的语言中,您可以定义对其构造函数执行所需检查的类型,以及从文字自动转换的装箱方法。
(未测试的)
const expected = "4|";