【发布时间】:2012-12-01 14:33:29
【问题描述】:
我正在编写一个图形库以了解有关在 Haskell 中构建稍大一些的东西的更多信息,但我遇到了一个问题。
基本上,我试图将Edges 定义为一组两个点,一个from 点和一个to 点。但是,我有多种类型的边缘(加权/非加权),我不希望它们能够混入graphs。
所以,我的想法是创建几个新类,Weighted 和 Edgy,以便能够实现我正在努力实现的多态行为数量。 Edge 的两种类型都将为Edgy,但只有加权Edge 类型将为Weighted。
Weighted 类很简单,因为它只需要修改整个对象。这是它的样子:
class Weighted a where
modifyWeight :: (Unbounded Int -> Unbounded Int) -> a -> a
Unbounded 是一个 Num 类型,我将它们组合在一起以支持无限大和小数。不过,这很简单,因为我只需要返回一个a。
我坚持的是让 Edgy 类返回类类型的类型(???不确定如何放置这个,可能是内部类型?)。为了更清楚地说明这一点,这是我正在使用的,可能更有意义:
class Edgy a where
to :: a -> Vertex a
from :: a -> Vertex a
Vertex 是一个包装类——我试图在这里声明的Edge:
data Edge a = Edge (Vertex a) (Vertex a) deriving (Show, Eq)
data WEdge a = WEdge (Vertex a) (Vertex a) (Unbounded Int) deriving (Show, Eq)
所以,我真正想做的是说“好吧,如果你是 Edgy 类的成员,你应该能够返回 Edge 类型的 Vertex” .
但是,GHC 不喜欢这样,因为 Edgy 中的 a 类型最终是 Edge a 而不是 a,我不知道如何让它“下降”到类拉出该类型以返回它。
如果有任何不清楚的地方,请发表评论。
非常感谢任何帮助;我被难住了!
谢谢!
【问题讨论】:
-
如果您说出您希望
Edgy拥有哪些实例,以及您希望to和from对这些实例拥有哪些类型,将会有所帮助。也就是说,我不相信你甚至需要在这里使用类型类——额外的复杂性真的在实践中发挥了作用吗(哈哈)? -
我想要
Edgy的Edge a和WEdge a实例。也许我应该稍微简化一下程序,你可能是对的,额外的复杂性是不必要的。不过,我正在尝试感受建造更大一点的东西是什么感觉,所以这就是走这条路线的想法。 -
如果您希望函数具有像
Edge a -> Vertex a这样的类型,那么最简单的事情就是 n.m. 的回答所暗示的。如果Edgy真的需要关心a参数,事情可能会更棘手。我仍然会先尝试在没有类型类的情况下制定它,然后看看它的外观。 -
顺便说一下,您可能喜欢内置的
Integer类型来替代Unbounded Int。 -
@DanielWagner 它支持 Infinity 吗?我知道整数是任意大的,但我想断言有一个数字是没有其他数字可以大于的。