我一直在玩一些 GHC 扩展来定义一个可以执行以下操作的函数:
let a = A :: A -- Show A
b = B :: B -- Show B
in
myFunc show a b -- This should return (String, String)
myFunc
的签名应该是完全多态的show
,这样它才能接受a
和b
满足不同的类型Show
。
这是我对 GHC 扩展的尝试RankNTypes
, ConstraintKinds
, KindSignatures
:
myFunc :: forall (k :: * -> Constraint) a b d. (k a, k b)
=> (forall c. k c => c -> d) -> a -> b -> (d, d)
我的主要目的是了解这些扩展是如何工作的;但在我看来,似乎我是在告诉 GHC 有k
一些满足的约束,a
还有b
一个函数(forall c. k c => c -> d)
可以采用任何c
满足的类型k
并返回一个特定的d
,现在,在这些条件下,我想应用该函数toa
和b
to 获得一个元组(d,d)
以下是 GHC 的抱怨方式:
Could not deduce (k0 a, k0 b)
from the context (k a, k b)
bound by the type signature for
myFunc :: (k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
at app/Main.hs:(15,11)-(16,56)
In the ambiguity check for the type signature for ‘myFunc’:
myFunc :: forall (k :: * -> Constraint) a b d.
(k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘myFunc’:
myFunc :: forall (k :: * -> Constraint) a b d. (k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
...
Could not deduce (k c)
from the context (k a, k b)
bound by the type signature for
myFunc :: (k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
at app/Main.hs:(15,11)-(16,56)
or from (k0 c)
bound by the type signature for myFunc :: k0 c => c -> d
at app/Main.hs:(15,11)-(16,56)
In the ambiguity check for the type signature for ‘myFunc’:
myFunc :: forall (k :: * -> Constraint) a b d.
(k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘myFunc’:
myFunc :: forall (k :: * -> Constraint) a b d. (k a, k b) =>
(forall c. k c => c -> d) -> a -> b -> (d, d)
app/Main.hs15:40
我错过了什么?