繁体   English   中英

您应该如何在Typed Racket中的letrec中键入相互注释的递归函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM