繁体   English   中英

在 F# 中将枚举转换为列表或序列或泛型集合类型

[英]converting an enum to a list or sequence or generic collection type in F#

我有一个类型是Dictionary<string,Node<'a>>*Edge<'a> listConcurrentDictionary<string,Node<'a>>*Edge<'a> list 我正在尝试创建一个get_nodes函数,但是当我从DictionaryConcurrentDictionary调用.Values时,这些函数返回不同的类型!

所以我需要以某种方式将这两种类型转换为相同的类型,以便 F# 编译...

Dictionary.Values给出的类型是Dictionary'2.ValueCollection<string,Node<'a>>ConcurrentDictionary产生的类型是ICollection<Node<'a>>

我发现这两种类型都有一个“GetEnumerator()”函数。 我需要做的是以某种方式将枚举器转换为 seq 或列表等。

这是我的代码:

   static member get_nodes (g:Graph<'a>) = 
        match g with 
        | Dictionary_Graph(nd,el) -> let n = nd.Values
                                     let enum = n.GetEnumerator()


        | ConcurrentDictionary_Graph(nd,el) -> let n = nd.Values
                                               let enum = n.GetEnumerator()

如何从枚举变量中提取数据?

您可能已经习惯了 C#,它会自动将 ValueCollection 向上转换为 ICollection(ValueCollection 实现)。 F# 不会这样做,因此您必须手动将 Dictionary.Values 的结果转换为 ICollection。

let n = nd.Values :> ICollection<Node<'a>>

完整方法看起来像这样:

static member get_nodes (g:Graph<'a>) = 
    match g with 
    | Dictionary_Graph(nd,el) ->
        nd.Values :> ICollection<Node<'a>>
    | ConcurrentDictionary_Graph(nd,el) ->
        nd.Values

据我了解,由于自动类型推理引擎的工作方式,F# 不会自动向上转换。 当您习惯了 C# 时,这很烦人,但为了获得自动类型推断而付出的代价是值得的。 还要考虑到,在 C# 中,您必须在方法的前面指定返回类型,这使得 C# 可以轻松地为您进行转换。 F# 引擎根据您实际返回的内容推断返回类型,因此最安全的做法是不要假设您希望它如何转换。

不是普遍共识,但我的意见是:我希望他们会为特定情况添加返回值的自动向上转换(例如提前声明输出类型或使分支符合上述要求),但现在这是一个小问题。

更新(来自评论中的问题)

ICollection<T>现在应该可以直接用作序列,因为它实现了IEnumerable<T> 在这种情况下,自动向上转换实际上确实有效。 :)

myGraph
|> Graph.get_nodes 
|> Seq.iter (fun x -> printfn "%A" x)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM