【发布时间】:2014-01-06 23:41:08
【问题描述】:
我对 Haskell 比较陌生,我相信我误解了关于类型类的一些基本知识。假设我想创建一个类型类“T”,实现由四种代数类型“A、B、C 和 D”支持的 n 元树,其结构规定最大深度为 4。这似乎是一个愚蠢的例子,但我认为它最能说明我的观点。
module Test where
class T t0 where
parent :: T t1 => t0 -> Maybe t1
children :: T t1 => t0 -> [t1]
data A = A [B]
instance T A where
parent (A _) = Nothing
children (A bs) = bs
data B = B A [C]
instance T B where
parent (B a _) = Just a
children (B _ cs) = cs
data C = C B [D]
instance T C where
parent (C b _) = Just b
children (C _ ds) = ds
data D = D C
instance T D where
parent (D c) = Just c
children (D _) = []
我想编写通用的父子函数,但 GHC 没有。
Test.hs:10:27:
Could not deduce (t1 ~ B)
from the context (T t1)
bound by the type signature for children :: T t1 => A -> [t1]
at Test.hs:10:9-28
`t1' is a rigid type variable bound by
the type signature for children :: T t1 => A -> [t1]
at Test.hs:10:9
Expected type: [t1]
Actual type: [B]
In the expression: bs
In an equation for `children': children (A bs) = bs
In the instance declaration for `T A'
Test.hs:14:31:
Could not deduce (t1 ~ A)
from the context (T t1)
bound by the type signature for parent :: T t1 => B -> Maybe t1
at Test.hs:14:9-31
`t1' is a rigid type variable bound by
the type signature for parent :: T t1 => B -> Maybe t1
at Test.hs:14:9
In the first argument of `Just', namely `a'
In the expression: Just a
In an equation for `parent': parent (B a _) = Just a
Test.hs:15:29:
Could not deduce (t1 ~ C)
from the context (T t1)
bound by the type signature for children :: T t1 => B -> [t1]
at Test.hs:15:9-30
`t1' is a rigid type variable bound by
the type signature for children :: T t1 => B -> [t1]
at Test.hs:15:9
Expected type: [t1]
Actual type: [C]
In the expression: cs
In an equation for `children': children (B _ cs) = cs
In the instance declaration for `T B'
Test.hs:19:31:
Could not deduce (t1 ~ B)
from the context (T t1)
bound by the type signature for parent :: T t1 => C -> Maybe t1
at Test.hs:19:9-31
`t1' is a rigid type variable bound by
the type signature for parent :: T t1 => C -> Maybe t1
at Test.hs:19:9
In the first argument of `Just', namely `b'
In the expression: Just b
In an equation for `parent': parent (C b _) = Just bv
我(我想我)理解类型类根本不像 Java 接口,因为类级函数必须适用于所提供类型变量的任何可能值;调用者没有“决定”类型。我不明白为什么 GHC 不能推导出 (t1 ~ _),因为替换 t1 的类型始终是 'T' 的实例。我看到实例声明之间存在一种循环依赖关系,例如A 的实例声明取决于 B 的有效性,这取决于 A 和 C 的,依此类推,但我觉得 GHC 足够聪明,可以弄清楚这一点,而我只是错过了一些东西。每当我希望类型类中的函数接受类中的一种类型但返回另一种类型时,我似乎总是会收到此错误...有没有办法使用类型类来完成此操作?
我看到这里有许多措辞相似的问题,但我还没有找到一个与我的问题相匹配的问题(据我所知)。
提前致谢。
【问题讨论】:
标签: haskell functional-programming typeclass