与AllowAmbiguousTypes
扩展程序一起使用时,TypeApplications
扩展程序有多危险?
GHC手册给出了以下模糊类型的示例:
class C a
f :: C a => Int
f = 3
如果不使用AllowAmbiguousTypes
并且出现以下消息,则无法编译:
file.hs:8:6: error:
• Could not deduce (C a0)
from the context: C a
bound by the type signature for:
f :: forall a. C a => Int
at file.hs:8:6-15
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘f’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature: f :: C a => Int
|
8 | f :: C a => Int
| ^^^^^^^^^^
使用AllowAmbiguousTypes
,它可以正确编译。
但是,即使使用AllowAmbiguousTypes
:
class C a
f :: C a => Int
f = 3
g :: C a => Int
g = f
尝试编译时出现以下错误:
file.hs:12:5: error:
• Could not deduce (C a0) arising from a use of ‘f’
from the context: C a
bound by the type signature for:
g :: forall a. C a => Int
at file.hs:11:1-15
The type variable ‘a0’ is ambiguous
• In the expression: f
In an equation for ‘g’: g = f
|
12 | g = f
| ^
这可以通过启用TypeApplications
并按如下方式编写来编写:
class C a
f :: C a => Int
f = 3
g :: forall a. C a => Int
g = f @a
AllowAmbiguousTypes
听起来很可怕,但根据GHC手册中的说明,它似乎非常温和,尤其是与TypeApplications
一起使用时。
不像AllowAmbiguousTypes
会导致运行时错误,对吧?
AllowAmbiguousTypes
和TypeApplications
的这种组合似乎也在一些非常受欢迎的软件包中使用,例如constraints。
答案 0 :(得分:4)
TypeApplications
是完全安全的,因为它完全合理,不会使编译器发散,也不会导致运行时错误。在引入<mat-select>
之前,它几乎没用。两者的结合是完全合理的。