简单类型的球拍程序不进行类型检查

时间:2014-04-13 17:50:29

标签: scheme racket typechecking typed-racket

我是Typed Racket的初学者,我正在玩Beginner's Guide中定义的非常简单的Tree类型:

#lang typed/racket
(define-type Tree (U leaf node))
(struct: leaf ([val : Number]))
(struct: node ([left : Tree] [right : Tree]))

作为练习,我决定编写一个高阶函数来下降树:

(: tree-descend : All (A) (Number -> A) (A A -> A) Tree -> A)
(define (tree-descend do-leaf do-node tree)
  (if (leaf? tree)
      (do-leaf (leaf-val tree))
      (do-node (tree-descend do-leaf do-node (node-left tree))
               (tree-descend do-leaf do-node (node-right tree)))))

此类型检查正常。但是,当我尝试使用它来重新定义遍布叶子的tree-sum函数时,我得到一条令人惊讶且冗长的错误消息:

(: tree-sum : Tree -> Number)
(define (tree-sum t)
  (tree-descend identity + t))

错误消息是

Type Checker: Polymorphic function `tree-descend' could not be applied to arguments:
  Argument 1:
    Expected: (Number -> A)
    Given:    (All (a) (a -> a))
  Argument 2:
    Expected: (A A -> A)
    Given:    (case-> (-> Zero) (Zero Zero -> Zero) (One Zero -> One) 
               (Zero One -> One) (Positive-Byte Zero -> Positive-Byte)  
               [...lots of ways of combining subtypes of Number...]
               (Index Positive-Index Index -> Positive-Fixnum) 
               (Index Index Positive-Index -> in: (tree-descend identity + t)

现在,对于我未经训练的眼睛,它看起来应该可以正常工作,因为显然多态类型A应该只是Number然后一切正常。显然,语言由于某种原因不同意我,但我不确定这是什么原因。

1 个答案:

答案 0 :(得分:4)

不幸的是,当你将多态函数应用于像tree-descend这样的多态参数时,Typed Racket无法推断出像identity这样的多态函数的正确实例化。如果您将identity替换为(inst identity Number),那么程序运行正常。