3

我正在尝试从Map. 这就是我所做的:

Map.fold (fun state key value -> state::value) [] [("one", 1); ("two", 2)]

但是,该位state::value会产生此错误:

tryout.fs(146,48): error FS0001: Type mismatch. Expecting a
    'a    
but given a
    'a list

我的代码有什么问题?

4

2 回答 2

4

其他人已经发布了很好的解决方案,所以只是为了回答你的问题并解释你的代码有什么问题——因为你正在使用Map.fold我假设你的数据源实际上是一个地图而不是一个列表:

let sample = Map.ofSeq [("one", 1); ("two", 2)]

这是您的原始解决方案,并且可以并排工作:

// Original version - attempts to add 'state' as the new head of a list 'value'
Map.fold (fun state key value -> state::value) [] sample
// Corrected version - adds 'key' as the new head of a list 'state'
Map.fold (fun state key value -> key::state) [] sample

关键是::运算符需要string在左侧有一个值(此处),右侧有另一个列表(此处string list)。您正确地创建了一个空列表[]作为初始状态。

当您想在折叠过程中添加新键时,您需要将现有列表 ( state) 作为右参数传递,::并将新键 ( key) 作为左参数传递 - 以创建一个包含键作为第一个元素的新列表,并且所有剩余的元素作为列表的其余部分(tail)。

所以 1)::事物的参数顺序和 2)你想收集键而不是值,但如果你正在收集值,它会以相同的方式工作。

于 2013-10-08T15:47:58.363 回答
1

两个问题:

- 你传递的不是地图而是列表。

- 状态(你的键被折叠成的结果)和值(一个 int)被反转。

您可以将列表转换为地图(请参阅 Daniel 的评论):

["one", 1; "two", 2]
|> Map.ofList
|> Map.fold (fun state key value -> value :: state) [];;
// val it : int list = [2; 1]

或者,您可以折叠元组列表:

["one", 1; "two", 2]
|> List.fold (fun state (key, value) -> value :: state) [];;
// val it : int list = [2; 1]
于 2013-10-08T15:42:57.503 回答