很抱歉打扰这个简单的问题。我试图了解类型系列扩展的工作原理。当我愚弄它时,我遇到了一个错误,我无法弄清楚原因。
class Foo a b c where
data T a b c :: *
f :: a -> T a b c
g :: T a b c -> b
h :: c -> a -> b
h c a = g $ f a
错误讯息:
Could not deduce (Foo a b c0) arising from a use of ‘g’
from the context (Foo a b c)
bound by the class declaration for ‘Foo’
at DB/Internal/Typecast.hs:(17,1)-(25,19)
The type variable ‘c0’ is ambiguous
Relevant bindings include
a :: a (bound at DB/Internal/Typecast.hs:25:9)
h :: c -> a -> b (bound at DB/Internal/Typecast.hs:25:5)
In the expression: g
In the expression: g $ f a
In an equation for ‘h’: h c a = g $ f a
我不明白T a b c
g
中的{c}是多么含糊不清。编译器是否可以从c
的{{1}}获取T a b c
的类型?
我只想要f
答案 0 :(得分:4)
请注意,在定义中
h :: c -> a -> b
h c a = g $ f a
f
和g
没有限制引用您为h
定义的相同的实例。 (这种灵活性通常对定义实例很有用。)
从类型推断,g
的结果被限制为同一类型b
,而f
的参数被限制为类型a
,但没有任何说明T a b c
从一个传递到另一个的c
使用相同的ScopedTypeVariables
!
要解决此问题,您可以启用 h c a = g (f a :: T a b c)
并执行
T a b c
请注意,这是有效的,因为数据系列是" injective" (数据族的类型参数可以从最终类型推导出来)。如果您使用的是类型系列,那么即使这样也行不通,因为c
根本不一定会确定{{1}}。