Haskell 控制多类类型类中的类型应用程序顺序
我正在使用GHC 8.4.2。我有这个打字班:Haskell 控制多类类型类中的类型应用程序顺序,haskell,Haskell,我正在使用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 _
{-# 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
方法时,结果是我需要指定kindk
作为第一个类型参数,否则它将无法工作:
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}
似乎意味着该类型是推断的
唉,我需要命名这种类型,因为在我的真实签名中,我需要说“这种类型与另一种类型具有相同的类型,不管是什么类型”。您可以编写
@
并让GHC推断出这种类型的参数:foo@\u@True Proxy
我相信类型应用程序的顺序始终是类型变量在:t
的输出中出现的顺序
例如,
:tfoo
给出了foo::forall k(a::k)。Foo a=>Proxy a->Int
,其中k
出现在第一个a
之前的forall
中,谢谢。然而,我的实际用例依赖于-xallowambigioustypes
-所有方法都需要类型应用程序。必须在每次调用中添加@
会极大地妨碍可用性。那么foo(Proxy@Char)
和foo(Proxy'True)
呢?应正确推断出k
。我不认为有一种方法可以让一些类型参数保留为合法的,而在函数中保留一些显式的,就像我们可以为构造函数所做的那样(比如Proxy
,它是多类型的,但保留了k
隐式的AFAIC)。在Coq/Agda中,隐式/显式的东西可以更容易地控制,但在Haskell中,我们没有相同的工具。@chi这会起作用,但会使我的实际API使用起来更麻烦。我有类似于insertI@“name”5的调用
。由于GHC建议#26:“显式专用性”,您应该能够编写类Foo(a::k),其中{Foo'::Int};foo::forall{k::Type}(a::k)。fooa=>Int;foo=foo'@k@a
在将来的某个时候。不作此回答,因为它在当前GHC Haskell中不起作用。有趣的事实是,foo
的签名看起来不可思议地像中给出的例子。