有限拟阵M是一对(E,I),其中E是有限集(称为地集),I是E的子集族(称为独立集)。
加权拟阵是具有权重函数w的拟阵W:E - > Int(正整数)。
我们可以按如下方式定义(加权)matroid类型类:
{-# 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是权函数。为了从图中定义一个matroid,我们将地面集作为边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
答案 0 :(得分:3)
错误消息表明GHC不知道Matroid
所需的weightedG
个实例。
它知道你想要某种类型Matroid WGraph a
的{{1}},而且你有。{1}}
定义了一个实例a
,但由于类型类是开放的,GHC无法断定Matroid Graph Edge
必须是a
。稍后或在另一个模块中,您(或其他人)可以定义Edge
实例 - 例如。
解决这个问题的一种方法是在matroid类型和元素类型之间引入功能依赖,如下所示:
Matroid WGraph String
这告诉GHC {-# LANGUAGE FunctionalDependencies #-}
class Matroid matroid a | matroid -> a where
...
类型确定边缘类型matroid
。通过这个改变,我得到了你的代码来编译。