GHCi 可以在 `:type <expr>` 命令中执行替换吗?
Can GHCi perform substitutions in `:type <expr>` commands?
GHCi :type <expr>
显示表达式的类型:
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi 能否在替换任何类型变量后显示结果?例如,让f = ((->) c)
,然后
:t (<*>) :: ((->) c) (a->b) -> ((->) c) a -> ((->) c) b
(<*>) :: ((->) c) (a->b) -> ((->) c) a -> ((->) c) b
:: (c -> a -> b) -> (c -> a) -> c -> b
有没有办法让 GHCi 计算出这些替换?
是的,有几种方法。许多操作使它们的类型变量成为它们 API 的一部分,您可以通过打开正确的选项并以正确的方式询问来观察这一点。
> :set -fprint-explicit-foralls
> :t +v (<*>)
(<*>)
:: forall (f :: * -> *).
Applicative f =>
forall a b. f (a -> b) -> f a -> f b
这实际上看起来并没有那么特别,但说明了一些重要的事情:因为 forall
d 类型变量没有用大括号括起来,所以它们可以成为类型应用程序的主题。 (但是你应该相信 "braces"/"not braces" 区分 only in :t +v
queries!正常 :t
munges type-application-availability in一种可能从 GHC 版本更改为 GHC 版本的脆弱方式。)
> :set -XTypeApplications
> :t (<*>) @((->) _)
(<*>) @((->) _)
:: forall {w} {a} {b}. (w -> a -> b) -> (w -> a) -> w -> b
有时您会发现不能以这种方式使用类型应用程序的术语。例如:
> :t +v \f x -> f <*> x
\f x -> f <*> x
:: forall {f :: * -> *} {a} {b}.
Applicative f =>
f (a -> b) -> f a -> f b
这里的大括号表示没有可用于类型应用的类型。我们运气不好吗?不,我们仍然可以使用类型孔来只填充我们关心的部分,然后向 GHC 询问其余部分。
> :set -XPartialTypeSignatures
> :set -Wno-partial-type-signatures
> :t (\f x -> f <*> x) :: ((_ -> _) -> _)
(\f x -> f <*> x) :: ((_ -> _) -> _)
:: forall {w} {a} {b}. (w -> a -> b) -> (w -> a) -> w -> b
GHCi :type <expr>
显示表达式的类型:
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi 能否在替换任何类型变量后显示结果?例如,让f = ((->) c)
,然后
:t (<*>) :: ((->) c) (a->b) -> ((->) c) a -> ((->) c) b
(<*>) :: ((->) c) (a->b) -> ((->) c) a -> ((->) c) b
:: (c -> a -> b) -> (c -> a) -> c -> b
有没有办法让 GHCi 计算出这些替换?
是的,有几种方法。许多操作使它们的类型变量成为它们 API 的一部分,您可以通过打开正确的选项并以正确的方式询问来观察这一点。
> :set -fprint-explicit-foralls
> :t +v (<*>)
(<*>)
:: forall (f :: * -> *).
Applicative f =>
forall a b. f (a -> b) -> f a -> f b
这实际上看起来并没有那么特别,但说明了一些重要的事情:因为 forall
d 类型变量没有用大括号括起来,所以它们可以成为类型应用程序的主题。 (但是你应该相信 "braces"/"not braces" 区分 only in :t +v
queries!正常 :t
munges type-application-availability in一种可能从 GHC 版本更改为 GHC 版本的脆弱方式。)
> :set -XTypeApplications
> :t (<*>) @((->) _)
(<*>) @((->) _)
:: forall {w} {a} {b}. (w -> a -> b) -> (w -> a) -> w -> b
有时您会发现不能以这种方式使用类型应用程序的术语。例如:
> :t +v \f x -> f <*> x
\f x -> f <*> x
:: forall {f :: * -> *} {a} {b}.
Applicative f =>
f (a -> b) -> f a -> f b
这里的大括号表示没有可用于类型应用的类型。我们运气不好吗?不,我们仍然可以使用类型孔来只填充我们关心的部分,然后向 GHC 询问其余部分。
> :set -XPartialTypeSignatures
> :set -Wno-partial-type-signatures
> :t (\f x -> f <*> x) :: ((_ -> _) -> _)
(\f x -> f <*> x) :: ((_ -> _) -> _)
:: forall {w} {a} {b}. (w -> a -> b) -> (w -> a) -> w -> b