[英]type signature golfing (or not) in Haskell
Could GHC golf out this extra type annotation or does it bring something real? GHC 可以打出这个额外的类型注释还是带来一些真实的东西?
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module SOQuestionInstanceQuantification2 where
class IsomorphismFromTo a b where -- :~:
isofromto :: forall p. p a -> p b
to :: a -> b
--to = (isofromto) @((->) a) id -- Bad without (redundant ?) annotation
to = (isofromto :: (forall p. p a -> p b)) @((->) a) id -- Good with (redundant ?) annotation
edit: removed superfluous DefaultSignatures
编辑:删除了多余DefaultSignatures
The real signature of isofromto
includes the type variables from the class: isofromto 的真正签名包括来自isofromto
的类型变量:
isofromto :: forall a b. IsomorphismFromTo a b => forall p. p a -> p b
Therefore, if we want to be explicit on p
, we need to write因此,如果我们想明确p
,我们需要写
to = isofromto @a @b @((->) a) id
to pass those argument as well.也传递这些论点。 Alternatively,或者,
to = isofromto @_ @_ @((->) a) id
makes those arguments to be inferred.使那些 arguments 被推断出来。
In the longer alternative在更长的选择中
to = (isofromto :: (forall p. p a -> p b)) @((->) a) id
the signature is not redundant, since it fixes the a
and b
type arguments.签名不是多余的,因为它修复了a
和b
类型 arguments。
Note that, in the general case, having to pass these additional arguments is needed since we might want to call, within to @a @b
, an implementation of isofromto
from another instance eg isofromto @(a,b) @(b,a)
.请注意,在一般情况下,必须传递这些额外的 arguments 是必需的,因为我们可能希望在to @a @b
中调用另一个实例的isofromto
实现,例如isofromto @(a,b) @(b,a)
.
Of course, Haskell could have a notation to indicate "call isofromto
from the current instance", without additional type arguments, but has not.当然,Haskell 可以有一个表示法来指示“从当前实例调用isofromto
”,没有额外的类型 arguments,但没有。 I guess in regular programming type inference already covers most cases, and when it's not enough, type applications already provide a means to choose the instance we need (including the current one), so I guess there is no strong need for such a special notation.我猜在常规编程中类型推断已经涵盖了大多数情况,当它还不够时,类型应用程序已经提供了一种选择我们需要的实例(包括当前实例)的方法,所以我想没有强烈需要这种特殊的符号.
For this kind of question in the future, you can ask ghci what's going on:以后遇到这种问题,可以问ghci是怎么回事:
> :set -fprint-explicit-foralls
> :t +v isofromto
isofromto
:: forall a b (p :: * -> *). IsomorphismFromTo a b => p a -> p b
This makes it very clear that a
and b
are the first two type arguments.这很清楚a
和b
是前两种类型arguments。 I recommend adding something like this to your ~/.ghci
;我建议在您的~/.ghci
中添加类似的内容; it's quietly saved my bacon a bunch of times.它悄悄地救了我的培根很多次。
:set -fprint-explicit-foralls
:def t Prelude.return Prelude.. (":type +v "Prelude.++)
The second line aliases :t
to :type +v
, so you don't need to remember the +v
when you need it most.第二行将:t
别名为:type +v
,因此在最需要的时候不需要记住+v
。 In the rare case that you actually want :t
without +v
, it is still available as :type
.在极少数情况下,您实际上需要:t
而没有+v
,它仍然可以作为:type
。
These two pieces together ( +v
and print-explicit-foralls
) will show you which type variables (if any) are available for application, and in which order.这两部分一起( +v
和print-explicit-foralls
)将向您显示哪些类型变量(如果有)可用于应用程序,以及以何种顺序。 Type variables that are not available for type application will be enclosed in curly braces:不能用于类型应用的类型变量将用花括号括起来:
> :t +v id id
id id :: forall {a}. a -> a
Missing one or the other of print-explicit-foralls
or +v
will lie in some situations.在某些情况下,缺少print-explicit-foralls
或+v
中的一个或另一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.