我目前正在尝试为Haskell编写GraphML阅读器(请参见this previous question)。由于我对Haskell还是很陌生,尽管学习难度很大,但我还没有完全学会仅从Hackage文档中推断示例的能力。
我目前拥有的是一个Graph
实例:
data Graph = Graph
{ graphId :: String,
nodes :: [String],
edges :: [(String, String)] -- (Source, target)
}
deriving (Show, Eq)
我想将它们转换为Data.Graph。我假设
graphFromEdges
或graphFromEdges'
是执行此操作的正确函数。我目前的尝试是创建3元组
(nodeid, nodeid, [edge targets])
-- Convert a graph node into a Data.Graph-usable
getDataGraphNode :: Graph -> String -> (String, String, [String])
getDataGraphNode graph node = (node, node, getTargets node graph)
-- Convert a Graph instance into a Data.Graph list of (node, nodeid, edge) tuples
getDataGraphNodeList :: Graph -> [(String, String, [String])]
getDataGraphNodeList graph = map (getDataGraphNode graph) (nodes graph)
但是,由于类型错误,GHC不会编译此代码:
Couldn't match expected type `[(node0, key0, [key0])]'
with actual type `(String, String, [String])'
您能指出一个例子,还是最好描述一下从文档中推断出一个例子的一般方法(在这种情况下是函数签名)?我是否需要使用Data.Graph中的
Vertex
类型?我目前无法确定node0
和key0
类型是什么。这是一个最小的示例,显示了我在
Data.Graph
中遇到的问题。我不确定这与滥用类型有什么关系,即使我自己的代码中的许多错误是由于类型系统的问题而发生的:import Data.Graph
main = do
graph <- graphFromEdges' [("n0","n0",["n1"]), ("n1","n1",["n2"]), ("n2","n2",[])]
-- This should print ["n0","n1","n2"]
print $ vertices graph
它产生以下错误信息:
bar.hs:4:5:
Couldn't match type `IO' with `(,) Graph'
Expected type: (Graph, ())
Actual type: IO ()
In a stmt of a 'do' block: print $ vertices graph
In the expression:
do { graph <- graphFromEdges'
[("n0", "n0", ["n1"]), ("n1", "n1", ["n2"]), ....];
print $ vertices graph }
In an equation for `main':
main
= do { graph <- graphFromEdges' [("n0", "n0", [...]), ....];
print $ vertices graph }
bar.hs:4:22:
Couldn't match type `Vertex -> ([Char], [Char], [[Char]])'
with `GHC.Arr.Array Vertex [Vertex]'
Expected type: Graph
Actual type: Vertex -> ([Char], [Char], [[Char]])
In the first argument of `vertices', namely `graph'
In the second argument of `($)', namely `vertices graph'
In a stmt of a 'do' block: print $ vertices graph
最佳答案
试试这个:
import Data.Graph
main = do
let (graph, vertexMap) = graphFromEdges' [("n0","n0",["n1"]), ("n1","n1",["n2"]),("n2","n2",[])]
-- This should print ["n0","n1","n2"]
print $ map ((\ (vid, _, _) -> vid) . vertexMap) (vertices graph)
graphFromEdges'
返回一对值,而Graph
是该对中的第一个。同样,在这种情况下,<-
用于返回IO something
的事物,而graphFromEdges'
返回纯值。关键错误是:
Couldn't match type `IO' with `(,) Graph'
Expected type: (Graph, ())
Actual type: IO ()
尽管报告的方式有些误导-如果您给
main
类型签名main :: IO ()
,则该报告会更好。通常,如果您对类型错误感到困惑,则值得尝试确定您认为应该是哪种类型,并使用显式类型签名。