我正在尝试从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
我的代码出了什么问题?
答案 0 :(得分:4)
其他人已经发布了很好的解决方案,所以只是回答你的问题并解释你的代码有什么问题 - 因为你正在使用Map.fold
我假设你的数据源实际上是一个地图而不是一个列表: / p>
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)你想要收集键而不是值,但如果你正在收集值,它将以相同的方式工作。
答案 1 :(得分: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]