Haskell 带有多种类的不明确种类变量

Haskell 带有多种类的不明确种类变量,haskell,ghc,polykinds,Haskell,Ghc,Polykinds,给定以下代码 {-#语言泛化newtypederiving} {-#语言MultiParamTypeClasses} {-#语言类型族{-} {-#语言多样性} 类型标记的族(m::*->*)::k 类示例(t::k)(a::*),其中 类型返回t a a::(单子m,标记为m~t)=>a->m(返回ta) 数据A 数据A'A 数据B=B 示例A和示例B,其中 类型返回ab=() a B=返回() --这就是为什么我想要一个“t” 实例A'B,其中 类型返回A'B=() a B=返回() 我得

给定以下代码

{-#语言泛化newtypederiving}
{-#语言MultiParamTypeClasses}
{-#语言类型族{-}
{-#语言多样性}
类型标记的族(m::*->*)::k
类示例(t::k)(a::*),其中
类型返回t a
a::(单子m,标记为m~t)=>a->m(返回ta)
数据A
数据A'A
数据B=B
示例A和示例B,其中
类型返回ab=()
a B=返回()
--这就是为什么我想要一个“t”
实例A'B,其中
类型返回A'B=()
a B=返回()
我得到了类型错误(指向行
a::(Monad m…

•无法推断:返回(标记为m)a~返回t a
来自上下文:(示例ta,Monad m,taged m~t)
受以下类型签名的约束:
a::(示例TA,单子m,标记m~t)=>
a->m(返回t a)
...
预期类型:a->m(返回t a)
实际类型:a->m(返回(标记m)a)
注意:“Return”是一个类型函数,可能不是内射函数
类型变量“k0”不明确
•在“a”的歧义检查中
要延迟歧义检查以使用站点,请启用AllowAmbigUstypes
检查类方法时:
a::对于所有k(t::k)a。
示例t a=>
forall(m::*->*)。
(单子m,带标记的m~t)=>
a->m(返回t a)
在“Example”的类声明中
我可以使用
Proxy t
a
引入一个参数,只要我在调用站点上签名:
test=a(Proxy::Proxy a)B
,这就是我想要避免的。我想要的是

newtype Test t m a=Test
{runTest::ma
}派生(函子、应用程序、单子)
类型实例已标记(测试TM)=t
test::Monad m=>test A m()
测试=a B
我希望使用类型实例从上下文
Test A m()
中找到
t
。考虑到删除种类注释、
PolyKinds
A'
的实例后模块将进行编译,这似乎是可能的。
k0
来自哪里


我想解决办法是放弃多种类,使用额外的数据类型,如
数据ATag;数据A'Tag;数据BTag
等。

这只是部分答案

我试着把这件事说清楚

type family Tagged k (m :: * -> *) :: k

class Example k (t :: k) (a :: *) where
  type Return k (t :: k) (a :: *)
  a :: forall m . (Monad m, Tagged k m ~ t) => a -> m (Return k t a)
并且,在启用了许多扩展之后,观察到:

> :t a
a :: (Example k (Tagged k m) a, Monad m) =>
     a -> m (Return k (Tagged k m) a)
因此,编译器正在抱怨,因为实例
Example k(标记为km)a
不能单独由
a,m
确定。也就是说,我们不知道如何选择
k

我猜,从技术上讲,我们可能有不同的
示例k(标记为kma
实例,例如,一个用于
k=*
,另一个用于
k=(*->*)


直觉上,知道
t
应该允许我们找到
k
,但是
Return
非内射阻止我们找到
t

“直觉上,知道t应该允许我们找到k,但Return非内射阻止我们找到t。”如果没有多种类的话,这个例子是用非内射族编译的,这难道不是不正确的吗?@tsm如果没有多种类的话,没有未知的
k
,只涉及种类
*
,所以这个问题就消失了。这是有意义的。我认为知道
t
会让我们知道
k
,不是吗@tsm知道
t
,因为
t
有类
k
,我想我们可以推断
k
。但是我们只知道
返回kta
,它不是内射的,不允许我们导出
t
是什么。