【问题标题】:Missing type for identifier in case statementcase 语句中缺少标识符类型
【发布时间】:2017-04-04 18:15:36
【问题描述】:

我正在尝试学习打字球拍,但遇到了一些类型注释问题。

#lang typed/racket
(require typed/racket/gui)

(define frame (new frame% [label "test frame"]))



(define tab-panel (new tab-panel% [parent frame] [choices '("One" "Two" "Three")]
                       [min-height 300] [min-width 300]
                       (callback
                               (lambda (tp e)
                                (case (send tp get-selection)
                                 ((0) (send tp change-children (lambda (children) (list a-panel))))
                                 ((1) (send tp change-children (lambda (children) (list b-panel))))
                                 ((2) (send tp change-children (lambda (children) (list c-panel)))))))))

(define a-panel (new panel% (parent tab-panel)))
(define a-text (new message% (parent a-panel) (label "A-panel")))
(define b-panel (new panel% (parent tab-panel)))
(define b-text (new message% (parent b-panel) (label "B-panel")))
(define c-panel (new panel% (parent tab-panel)))
(define c-text (new message% (parent c-panel) (label "C-panel")))

在 case 语句的行中生成以下错误:

. Type Checker: missing type for identifier;
 consider adding a type annotation with `:'
  identifier: a-panel in: a-panel
. Type Checker: missing type for identifier;
 consider adding a type annotation with `:'
  identifier: b-panel in: b-panel
. Type Checker: missing type for identifier;
 consider adding a type annotation with `:'
  identifier: c-panel in: c-panel
. Type Checker: Summary: 3 errors encountered in:
  a-panel
  b-panel
  c-panel

我一直在研究文档,但似乎无法找出用于解决此问题的类型声明的正确语法。

这不是家庭作业。我只是想学习打字球拍,因为我认为强打字是个好主意。

【问题讨论】:

    标签: scheme racket typed-racket


    【解决方案1】:

    您的 case 语句和 GUI 内容混淆了问题。有时通过尝试较小的示例可以更容易地找出问题所在。这里的问题与这个简单得多的程序中的问题相同:

    #lang typed/racket
    
    (define (list-abc)
      (list a b c))
    
    (define a 1)
    (define b 2)
    (define c 3)
    

    它必须知道abc的类型才能推断list-abc的类型。有两种方法可以解决这个问题。要么在 list-abc 上添加类型注释,要么在 abc 上添加类型注释。

    要么:

    (: list-abc : -> (Listof Integer))
    (define (list-abc)
      (list a b c))
    

    或者:

    (define a : Integer 1)
    (define b : Integer 2)
    (define c : Integer 3)
    

    这个更简单问题的解决方案也可以转化为更大的程序。您可以使用tab-panel 上的类型注释或a-panelb-panelc-panel 上的类型注释来解决它。

    对于您的程序,注释不会是(-> (Listof Integer))Integer,而是(Instance Tab-Panel%)(Instance Panel%)

    【讨论】:

    • 当我尝试在面板的定义中添加注释时,我收到一个没有意义的不同错误:Type Checker: parse error in type; type name 'panel%' is unbound in: panel%
      我知道这意味着什么,但发生错误是没有意义的。 panel% 定义在 typed/racket/gui
    • 好的。对象的类型是(Instance Class-Type),其中Class-Type 是类的类型。 panel% 的类型是 Panel%,所以它的对象的类型是 (Instance Panel%)。这在documentation for typed classes 中有描述。
    • 做到了!谢谢你。几十年来我一直在做 OO 编程,但我对 Typed Racket 还是很陌生。非常感谢您的帮助。
    • 好的。我明白你为什么认为类型只是类名。类型化的球拍类不直接用作类型,因为它们是一等值。相反,他们使用(Instance ...) 来区分对象类型和类类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2013-02-15
    • 1970-01-01
    • 2018-01-12
    • 2020-01-27
    • 2013-03-19
    • 1970-01-01
    相关资源
    最近更新 更多