提问人:Tom Price 提问时间:11/5/2023 更新时间:11/5/2023 访问量:20
类型化球拍中“with-handlers”的意外行为
Unexpected behaviour of `with-handlers` in typed Racket
问:
我正在尝试处理键入的 Racket 中的某些类型的错误。以下代码在类型化和非类型化 Racket 中都按预期工作
(with-handlers
([exn:fail:contract:divide-by-zero?
(lambda (e)
(raise e))])
(let ([x 0]
[y 1])
(display (/ y x))))
导致错误消息
/: division by zero
在未打字的 Racket 中稍作阐述:
(with-handlers
([exn:fail:contract:divide-by-zero?
(lambda (e)
(displayln "oops!")
(raise e))])
(let ([x 0]
[y 1])
(display (/ y x))))
oops!
/: division by zero
但在键入的 Racket 中给出以下错误消息:
Type Checker: No function domains matched in function application:
Domains: (U (Rec flat (U (Immutable-HashTable flat flat) (Immutable-Vectorof flat) (Pairof flat flat) Boolean Bytes Char Complex Keyword Null String Symbol)) exn) Any
(U (Rec flat (U (Immutable-HashTable flat flat) (Immutable-Vectorof flat) (Pairof flat flat) Boolean Bytes Char Complex Keyword Null String Symbol)) exn)
Arguments: Any
in: (raise e)
有人可以解释一下这里发生了什么,或建议解决方法吗?
答:
1赞
Shawn
11/5/2023
#1
虽然在普通的 Racket 中,要提出
的第一个参数可以是任何值,但由于某种原因,在 Typed Racket 中,它仅限于特定类型的列表,包括结构的层次结构。exn
我发现您几乎总是必须显式指定函数的参数类型;Typed Racket 通常不会推断它们并赋予它们通用类型。因此,要满足 的类型:Any
raise
#lang typed/racket/base
(with-handlers
([exn:fail:contract:divide-by-zero?
(lambda ([e : exn]) ; The type of a struct is usually the name of the struct
(displayln "oops!")
(raise e))])
(let ([x 0]
[y 1])
(display (/ y x))))
评论
0赞
Shawn
11/5/2023
有趣的是,为什么你的第一个例子在TR中有效;我怀疑像这样的表达式是在类型检查完成之前变成的,而更复杂的表达式不是这样内联的。(lambda (x) (f x))
f
0赞
Tom Price
11/6/2023
谢谢!在我最初的问题中,我忘了提到我也尝试过,它给出了与 TR 相同的结果。所以你也回答了一个我没有问:)的问题lambda ([e : Any])
lambda (e)
评论