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

时间:2015-11-10 15:55:12

标签: .net f#

我的类型是p3 = PointOnUnitCircle.from_angle(pi/4) Dictionary<string,Node<'a>>*Edge<'a> list。我正在尝试创建ConcurrentDictionary<string,Node<'a>>*Edge<'a> list函数,但当我从get_nodes.Values调用Dictionary时,函数会返回不同的类型!

因此我需要以某种方式将两种类型转换为F#的相同类型以进行编译...

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

我发现这两种类型都有一个&#34; GetEnumerator()&#34;功能。我需要做的是以某种方式将枚举器转换为seq或列表等。

这是我的代码:

ICollection<Node<'a>>

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

1 个答案:

答案 0 :(得分:3)

您可能习惯使用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)