我有一个关于功能依赖的问题。我的理解是,例如,如果我写class Graph g a b | g -> a, g -> b
,那么任何特定g
的都只能与一种类型相关联a
和b
。事实上,试图声明两个实例相同g
和不同a
并且b
不起作用。
但是,在以下情况下,编译器(ghc)似乎无法使用依赖项,
class (Eq a, Eq b) => Graph g a b | g -> a, g -> b where
edges :: g -> [b]
src :: g -> b -> a
dst :: g -> b -> a
vertices :: g -> [a]
vertices g = List.nub $ map (src g) (edges g) ++ map (dst g) (edges g)
class Graph g a b => Subgraph g a b | g -> a, g -> b where
extVertices :: g -> [b]
data Subgraph1 g where
Subgraph1 :: Graph g a b => g -> [b] -> Subgraph1 g
instance Graph g a b => Graph (Subgraph1 g) a b where
vertices (Subgraph1 g _) = vertices g
edges (Subgraph1 g _) = edges g
src (Subgraph1 g _) = src g
dst (Subgraph1 g _) = dst g
如果我Subgraph1
通过添加参数a
和b
类型签名来进行修改,那么一切都会成功。
data Subgraph1 g a b where
Subgraph1 :: Graph g a b => g -> [b] -> Subgraph1 g a b