3

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似乎也用于一些非常流行的包中,比如约束

4

1 回答 1

4

亚历克西斯·金在她的评论中指出了这一点。它应该被提升到答案的水平。

AllowAmbiguousTypes是完全安全的,从某种意义上说它是完美的,不会使编译器发散,也不会导致运行时错误。在引入TypeApplications. 两者的结合是完全合理的事情。

于 2018-04-06T14:56:47.537 回答