【发布时间】:2015-07-02 14:25:56
【问题描述】:
有限拟阵 M 是一对 (E, I),其中 E 是有限集(称为基集),I 是 E 的子集族(称为独立集)。
加权拟阵是配备权重函数 w 的拟阵 W:E -> Int(正整数)。
我们可以如下定义一个(加权的)拟阵类型类:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
class Matroid matroid a where
weight :: matroid -> a -> Int
groundSet :: matroid -> [a]
indepSet :: [a] -> Bool
然后我们可以为拟阵定义各种算法。例如,选择权重最小的基组 F。当应用于图时,这是 Kruskal 用于寻找最小权重生成树的算法。
(加权)拟阵的实例是(加权)图 G = (E, w),其中 E 是边的集合,w 是权重函数。为了从图中定义一个拟阵,我们将基集设为边 E 的集合,并且 E 的子集 F 是独立的当且仅当它是非循环的。
instance Matroid WGraph Edge where
weight = wT
groundSet = gSet
indepSet = iSet
type Vertex = Int
type Edge = (Vertex, Vertex)
type Graph = [Edge]
type WtFun = Edge -> Int
type WGraph = (Graph, WtFun)
gSet :: WGraph -> [Edge]
gSet (es,wt) = es
wT :: WGraph -> (WtFun)
wT (es,wt) = wt
-- stub
iSet :: [Edge] -> Bool
iSet edges = True
但是给定一个加权图,下面的代码有一个类型错误
weightedG = (es, wt)::WGraph
es = [(4,5),(6,7),(5,7)]::[Edge]
wt :: (Edge -> Int)
wt (4,5) = 15
wt (6,7) = 11
wt (5,7) = 9
gs = groundSet weightedG
No instance for (Matroid WGraph a0)
arising from a use of `groundSet'
The type variable `a0' is ambiguous
我们如何指定 a0 应该是 Edge 类型?
复制/粘贴代码:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
class Matroid matroid a where
weight :: matroid -> a -> Int
groundSet :: matroid -> [a]
indepSet :: [a] -> Bool
instance Matroid WGraph Edge where
weight = wT
groundSet = gSet
indepSet = iSet
type Vertex = Int
type Edge = (Vertex, Vertex)
type Graph = [Edge]
type WtFun = Edge -> Int
type WGraph = (Graph, WtFun)
gSet :: WGraph -> [Edge]
gSet (es,wt) = es
wT :: WGraph -> (WtFun)
wT (es,wt) = wt
-- fix for real implementation
iSet :: [Edge] -> Bool
iSet edges = True
weightedG = (es, wt)::WGraph
es = [(4,5),(6,7),(5,7)]::[Edge]
wt :: (Edge -> Int)
wt (4,5) = 15
wt (6,7) = 11
wt (5,7) = 9
gs = groundSet weightedG
【问题讨论】: