简体   繁体   English

GHC 9 中的`forall {..}`

[英]`forall {..}` in GHC 9

This is valid syntax in GHC 9. What do the {..} mean (as distinct from (..) which GHC 8.10 requires here)?这是 GHC 9 中的有效语法。 {..}是什么意思(与 GHC 8.10 在这里要求的(..)不同)?

ign :: forall {f :: Type -> Type} {p}. Applicative f => p -> f ()
ign _ = pure ()

See 6.4.14.1.6.4.14.1。 Inferred vs. specified type variables : 推断与指定类型变量

  • .. is a specified type ..指定类型
  • {..} is an inferred type {..}推断类型

forall a. and forall {a}.forall {a}. are invisible quantifiers that GHC will instantiate automatically by unification.是 GHC 将通过统一自动实例化的不可见量词。

This means writing const True EQ actually instantiates a and b without the users help.这意味着编写const True EQ实际上会在没有用户帮助的情况下实例化ab

const :: forall a b. a -> b -> a
const a _ = a

If the user wants to explicitly instantiate them they can "override their visibility", using visible type applications.如果用户想要显式实例化它们,他们可以使用可见类型应用程序“覆盖它们的可见性”。 That's why they are specified types.这就是为什么它们是指定的类型。 (although "specifi able " might be a more accurate terminology) (尽管“特定”可能是更准确的术语)

>> :set -XTypeApplications
>> :t const @Bool @Ordering True EQ
const @Bool @Ordering True EQ :: Bool

If for some reason we only want to specify b (without summoning the "snail squad": @_ , umm " partial type signatures ") we can make a an inferred type.如果出于某种原因我们只想指定b (没有召唤“蜗牛小队”: @_ ,嗯“ 部分类型签名”),我们可以制作一个推断类型。 Then the first type is dropped然后第一种类型被丢弃

const2 :: forall {a} b. a -> b -> a
const2 a _ = a

>> :t const2 @Ordering True EQ
const2 @Ordering True EQ :: Bool

For your example it means ghc must infer the type of f and p .对于您的示例,这意味着 ghc 必须推断fp的类型。 You cannot write ign @IO @Int .你不能写ign @IO @Int


This becomes more useful when you have kind polymorphism.当你有一种多态性时,这变得更加有用。 If you define如果你定义

type    Apply :: forall (k :: Type). (k -> Type) -> (k -> Type)
newtype Apply f a where
  MkApply :: forall (k :: Type) (f :: k -> Type) (a :: k). f a -> Apply @k f a

you must specify the kind k when instantiating MkApply @Type @[] @Int but this kind is implied by both [] and Int .您必须在实例化MkApply @Type @[] @Int时指定类型k ,但[]Int都暗示了这种类型。

so you might prefer marking k as inferred in MkApply so you can write MkApply @[] @Int所以你可能更喜欢在MkApply k标记为推断,这样你就可以编写MkApply @[] @Int

type    Apply :: forall (k :: Type). (k -> Type) -> (k -> Type)
newtype Apply f a where
  MkApply :: forall {k :: Type} (f :: k -> Type) (a :: k). f a -> Apply @k f a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM