我正在使用GHC 8.4.2。我有这个类型类:
{-# LANGUAGE DataKinds, PolyKinds, TypeApplications #-}
import Data.Kind (Type)
import Data.Proxy
class Foo (a :: k) where
foo :: Proxy a -> Int
instance Foo True where
foo _ = 0
instance Foo Char where
foo _ = 0
这是真实案例的简化版本,需要多种多样。
当我尝试将TypeApplications
与foo
方法一起使用时,原来我需要将类型k
指定为第一个类型参数,否则它将无法正常工作: / p>
ghci> :t foo @Type @Char
foo @Type @Char :: Proxy Char -> Int
ghci> :t foo @Bool @True
foo @Bool @True :: Proxy 'True -> Int
在我的实际用例中,必须将种类指定为第一类型参数是很烦人的。无论如何,种类取决于第二种类型的参数。
是否有一种方法不必先提供种类,或者甚至根本不必提供种类,而仍然保持多品种?
此外,在使用ghci时,是否可以了解类方法的类型应用程序的正确顺序?
编辑。当我没有明确命名种类时,多余的参数就会消失,例如:
class Foo (a :: k) where
foo :: Proxy a -> Int
*Main> :set -fprint-explicit-foralls
*Main> :t +v foo
foo :: forall k (a :: k). Foo a => Proxy a -> Int
class Foo a where
foo :: Proxy a -> Int
*Main> :set -fprint-explicit-foralls
*Main> :t +v foo
foo :: forall {k} (a :: k). Foo a => Proxy a -> Int
在最后一个版本中,我们只需要提供一个类型参数即可。 {k}
似乎意味着可以推断出这种类型。
A,我需要命名这种类型,因为在我的真实签名中,我需要说“这种类型与另一种类型具有相同的类型,不管是什么。”
答案 0 :(得分:3)
您可以编写bindSomeInterface
并让GHC推断出实参:@_
我相信类型应用程序的顺序始终是类型变量在foo @_ @True Proxy
输出中出现的顺序。
例如,:t
给出:t foo
,其中foo :: forall k (a :: k). Foo a => Proxy a -> Int
在k
中出现在第一个forall
之前。