【发布时间】:2012-02-27 06:18:58
【问题描述】:
我正在做一个有趣的项目,我试图从 Java 中重做一些基本的数据类型和概念。目前我正在处理迭代器。
我的方法如下: (1) 将接口转换为类型类 (2) 为实际实现声明自定义数据类型和实例
所以我创建了以下类型类:
class Iterator it where
next :: it e -> (it e, e)
hasNext :: it e -> Bool
class Iterable i where
iterator :: Iterator it => i e -> it e
class Iterable c => Collection c where
add :: c e -> e -> c e
是的,我正在尝试翻译迭代器的概念(在这种情况下,它只是实际列表周围的一个框)。
这是我对一个简单列表的实现:
data LinkedList e = Element e (LinkedList e) | Nil
deriving (Show, Eq)
instance Collection LinkedList where
add Nil e = Element e Nil
add (Element x xs) e = Element x $ add xs e
为了简化,我排除了其他函数,如删除、包含、addAll。
这是迭代器:
data LinkedListIterator e = It (LinkedList e)
instance Iterator LinkedListIterator where
hasNext (It Nil) = False
hasNext (It _) = True
next (It (Element x xs)) = (It xs, x)
最后,Iterable LinkedList 的实例丢失了。我就是这样做的:
instance Iterable LinkedList where
iterator list = It list
迭代器函数将列表包装成LinkedListIterator 并返回它。这里 GHC 声明一个错误:
Could not deduce (it ~ LinkedListIterator)
from the context (Iterator it)
bound by the type signature for
iterator :: Iterator it => LinkedList e -> it e
`it' is a rigid type variable bound by
the type signature for
iterator :: Iterator it => LinkedList e -> it e
Expected type: it e
Actual type: LinkedListIterator e
我不太明白。 LinkedListIterator 有一个 Iterator 的实例,那么为什么预期的类型“it e”与实际类型“LinkedListIterator e”不兼容(据我了解,是一个 Iterator e) .波浪号 (~) 到底是什么意思?什么是刚性类型变量?
编辑:我将标题从 Translating Java Types into Haskell types: type deduction fail due to rigid type variable 更改为 Returning something from another type class B in function of type class A in Haskell 因为我相信我的实际问题与 return-something-of-type-class-B-from-type 有关-迭代器函数中的-class-A-issue。
解决方案:感谢答案,我现在将代码更改为以下版本。但是,我在阅读Typeclassopedia 时玩得很开心,只能推荐它。如前所述,应该学习 haskell 习语。
data Iterator c e = Next (Iterator c e, e) | Empty
deriving (Show, Eq)
next :: Iterator c e -> (Iterator c e, e)
next (Next (i, e)) = (i, e)
hasNext :: Iterator c e -> Bool
hasNext Empty = False
hasNext _ = True
class Iterable i where
iterator :: i e -> Iterator (i e) e
instance Iterable LinkedList where
iterator Nil = Empty
iterator (Element x xs) = Next (iterator xs, x)
【问题讨论】:
标签: java haskell types type-constraints