简体   繁体   English

在 Haskell 中键入签名打高尔夫球(或不打高尔夫球)

[英]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.签名不是多余的,因为它修复了ab类型 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.这很清楚ab是前两种类型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.这两部分一起( +vprint-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.

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