结合TypeApplications使用AllowAmbiguousTypes扩展的风险程度如何?
GHC歧义类型示例解析
咱们先看GHC手册里给出的这个歧义类型的例子,先修正下语法错误后的完整代码是这样的:
class C a where f :: C a => Int f = 3
当你没有启用AllowAmbiguousTypes编译选项时,这段代码会直接编译失败,报错信息如下:
file.hs:8:6: error:
• 无法从上下文C a推导出(C a0),该上下文由类型签名f :: forall a. C a => Int在file.hs:8:6-15处约束
• 类型变量‘a0’存在歧义
• 在对‘f’进行歧义性检查时...
错误原因拆解
问题核心出在f的类型签名forall a. C a => Int上:这里的类型变量a只出现在约束C a里,完全没有出现在返回值Int中。GHC默认的类型检查逻辑会认为这种类型是歧义的——它没办法确定到底要使用哪个具体的a实例来满足C a的约束,毕竟没有任何代码线索能推断出a的具体类型。
举个直观的例子:如果我们定义了C Int和C String两个不同的实例,当你调用f的时候,GHC根本不知道该选哪一个实例,自然就会抛出这个歧义错误。
而启用AllowAmbiguousTypes选项后,GHC会放宽这个检查,允许这种类型存在,但你之后调用f时,必须用类型应用(比如f @Int)来明确指定要使用的类型a,以此消除歧义。
内容的提问来源于stack exchange,提问作者illabout
相关产品推荐
相关产品推荐

