我似乎错过了一些基本的东西。
当我尝试使用sampleGraph
映射联接时出现此错误:
Main> map join sampleGraph
<interactive>:3:10:
Couldn't match expected type ‘[(Start, [End])]’
with actual type ‘Graph’
In the second argument of ‘map’, namely ‘sampleGraph’
In the expression: map join sampleGraph
这是代码
type Node = Integer
type Edge = (Node,Node)
type Start = Node
type End = Node
newtype Graph = Graph [(Start,[End])] deriving (Eq,Show)
join :: (Start, [End]) -> [Edge]
join (start, ends) = map (\ e -> if start < e then (start, e) else (e, start)) ends
sampleGraph = (Graph
[(5,[1,2,3]),
(7,[1,2]),
(1,[1,2]),
(2,[1,2])
])
答案 0 :(得分:3)
地图的类型是
map :: (a -> b) -> [a] -> [b]
在这种情况下,join具有类型
join :: (Start, [End]) -> [Edge]
所以map join
的类型为
map join :: [(Start, [End])] -> [[Edge]]
我们想要的是Graph -> [[Edge]]
。所以我们需要一个函数Graph -> [(Start, [End])]
,我们将全部设置好。幸运的是,对于记录访问器来说这非常简单!
type Node = Integer
type Edge = (Node, Node)
type Start = Node
type End = Node
newtype Graph = Graph {
edges :: [(Start, [End])]
} deriving (Eq, Show)
join :: (Start, [End]) -> [Edge]
join (start, ends) = map (\e -> if start < e then (start, e) else (e, start)) ends
sampleGraph =
Graph [(5, [1, 2, 3]),
(7, [1, 2]),
(1, [1, 2]),
(2, [1, 2])
]
foo = map join . edges
我们为edge字段声明了一个访问者edges
,并自动赋予Graph -> (Start, [End])
类型。撰写map join . edges
会产生最终所需的类型。
另一种方法是使用case-expression将Graph
破坏为其组成部分:
case sampleGraph of
Graph edges -> map join edges
生活是一种选择的自助餐。