Rei*_*ica 12 syntax haskell forall
这是 GHC 9 中的有效语法。这是什么意思(与GHC 8.10 此处要求的{..}不同)?(..)
ign :: forall {f :: Type -> Type} {p}. Applicative f => p -> f ()
ign _ = pure ()
Run Code Online (Sandbox Code Playgroud)
Ice*_*ack 11
自 9.0.1 版本以来,GHC 允许将用户编写的类型或种类变量标记为inferred,而不是默认的指定。通过将大括号中的类型变量绑定器写为
{tyvar}or{tyvar :: kind},新变量将被归类为推断变量,而不是指定变量。
..是指定类型{..}是推断类型forall a.和forall {a}.是 GHC 将通过统一自动实例化的不可见量词。
const :: forall a b. a -> b -> a
const a _ = a
Run Code Online (Sandbox Code Playgroud)
这意味着无需用户帮助即可const True EQ实例化a ( @Bool) 和b ( ) 。@Ordering
如果用户想要显式实例化它们,他们可以使用可见类型应用程序“覆盖它们的可见性”。这就是为什么它们是指定类型的原因。(尽管“特定”可能是更准确的术语)
>> :set -XTypeApplications
>> :t const @Bool @Ordering True EQ
const @Bool @Ordering True EQ :: Bool
Run Code Online (Sandbox Code Playgroud)
如果出于某种原因我们只想指定b(而不召唤“蜗牛小队”:@_,嗯“部分类型签名”),我们可以将a设为推断类型。然后第一个类型被删除
const2 :: forall {a} b. a -> b -> a
const2 a _ = a
>> :t const2 @Ordering True EQ
const2 @Ordering True EQ :: Bool
Run Code Online (Sandbox Code Playgroud)
对于您的示例,这意味着 ghc 必须推断f和p的类型。你不能写ign @IO @Int。
当您具有善良的多态性时,这会变得更有用。如果你定义
-- MkApply @Type @[] @Int :: [Int] -> Apply @Type [] Int
-- MkApply @_ @[] @Int :: [Int] -> Apply @Type [] 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
Run Code Online (Sandbox Code Playgroud)
实例化时必须指定k类型,但和MkApply @Type @[] @Int都隐含了这种类型。您可能更喜欢将k标记为 inferred,这样您就可以编写[]IntMkApplyMkApply @[] @Int
-- MkApply @[] @Int :: [Int] -> Apply @Type [] 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
Run Code Online (Sandbox Code Playgroud)