[英]How should you type annotate mutually recursive functions in letrec in Typed Racket?
如果我正确理解,这是注释Typed Racket中letrec
中定义的函数的正确方法:
#lang typed/racket
(letrec ((is-even? (lambda ((n : Nonnegative-Integer))
: Boolean
(or (zero? n)
(is-odd? (sub1 n)))))
(is-odd? (lambda ((n : Nonnegative-Integer))
: Boolean
(and (not (zero? n))
(is-even? (sub1 n))))))
(is-odd? 11))
但这给出了错误信息:
Type Checker: insufficient type information to typecheck. please add more
type annotations in: is-odd?
解决方法是这样的:
(local ((: is-even? : Nonnegative-Integer -> Boolean)
(define (is-even? n)
(or (zero? n)
(is-odd? (sub1 n))))
(: is-odd? : Nonnegative-Integer -> Boolean)
(define (is-odd? n)
(and (not (zero? n))
(is-even? (sub1 n)))))
(is-odd? 11))
也可以使用传统表示法的形式,例如该问题,但我希望也能够使用当前表示法对letrec
进行注释。
您可以在letrec
的函数名称之后添加类型注释,如下所示:
(letrec ([f1 : type1 expr1]
[f2 : type2 expr2])
body)
以您的示例为例:
(letrec ([is-even? : (-> Nonnegative-Integer Boolean)
(lambda (n)
(or (zero? n)
(is-odd? (sub1 n))))]
[is-odd? : (-> Nonnegative-Integer Boolean)
(lambda (n)
(and (not (zero? n))
(is-even? (sub1 n))))])
(is-odd? 11))
为什么这样做有效,但在lambda
内放置类型注释却不能呢?
这是因为确保每个lambda
类型检查都依赖于is-odd?
类型is-odd?
is-even?
分别。 但是,如果您不直接注释函数名,则只能尝试通过对lambda进行类型检查来推断这些类型。
直接注释函数名意味着在知道什么类型is-even?
之前,它甚至不必查看lambda is-even?
is-odd?
一定有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.