首页 > 解决方案 > 在 Haskell 中输入签名打高尔夫球(或不打高尔夫球)

问题描述

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

编辑:删除多余的DefaultSignatures

标签: haskell

解决方案


真正签名isofromto包括来自类的类型变量:

isofromto :: forall a b. IsomorphismFromTo a b => forall p. p a -> p b

因此,如果我们想明确p,我们需要写

to = isofromto @a @b @((->) a) id

也传递这些论点。或者,

to = isofromto @_ @_ @((->) a) id

使这些论点被推断出来。

在更长的选择中

to = (isofromto :: (forall p. p a -> p b)) @((->) a) id

签名不是多余的,因为它修复了ab类型参数。

请注意,在一般情况下,需要传递这些额外的参数,因为我们可能希望在 内调用来自另一个实例to @a @b的实现,isofromto例如isofromto @(a,b) @(b,a)

当然,Haskell 可以有一个符号来表示“isofromto从当前实例调用”,没有额外的类型参数,但没有。我猜在常规编程中类型推断已经涵盖了大多数情况,当它还不够时,类型应用程序已经提供了一种选择我们需要的实例(包括当前实例)的方法,所以我想没有强烈需要这种特殊的符号.


推荐阅读