转换一个枚举在F#列表或序列或泛型集合类型 [英] converting an enum to a list or sequence or generic collection type in F#

查看:126
本文介绍了转换一个枚举在F#列表或序列或泛型集合类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类型,要么是词典<字符串,节点<A>> *边及LT;A>清单 ConcurrentDictionary<字符串,节点<A>> *边及LT;A>清单。我想创建一个 get_nodes 的功能,但是当我打电话 .Values​​ 词典 ConcurrentDictionary ,该函数将返回不同的类型!

所以,我需要以某种方式转变这两种类型的入同一类型的F#编译...

Dictionary.Values​​ 给出的类型是 Dictionary'2.ValueCollection<字符串,节点<A>> 而>按 ConcurrentDictionary 的ICollection<节点<A>>

我想通了,这两种类型有一个的GetEnumerator()函数。我需要做的就是以某种方式把调查员到一个序列或列表等。

下面是我的code:

 静态成员get_nodes(G:图形<A>)=
        匹配摹与
        | Dictionary_Graph(ND,EL) - >令n = nd.Values
                                     让枚举= n.GetEnumerator()


        | ConcurrentDictionary_Graph(ND,EL) - >令n = nd.Values
                                               让枚举= n.GetEnumerator()
 

我如何提取数据出来的枚举变量?

解决方案

您可能正在使用C#这将自动向上转型的ValueCollection到ICollection的(这ValueCollection实现)

。 F#不这样做,所以你必须手动施放Dictionary.Values​​的结果ICollection的。

 令n = nd.Values​​:> ICollection的<节点<A>>
 

完整的方法将是这个样子:

 静态成员get_nodes(G:图形<A>)=
    匹配摹与
    | Dictionary_Graph(ND,EL) - >
        nd.Values​​:> ICollection的<节点<A>>
    | ConcurrentDictionary_Graph(ND,EL) - >
        nd.Values
 

据我了解,F#不自动向上转型,因为的方式,自动型推理引擎的工作原理。这是刺激性的,当你使用C#,但它是一个值得付出得到自动类型推断的价格。同时认为,在C#中,你必须指定返回类型前面的方法,这很容易让C#做投给你。 F#发动机推断根据你实际回报是什么返回类型,所以最安全的事情是不是让你想怎么把它转换假设。

不是一般的共识,但我的观点:我希望他们会增加对特定情况下的返回值自动向上转型(如输出类型声明提前或使分支机构符合如上),但它是一个轻微的刺激,现在。

更新(从评论的问题)

的ICollection< T> 现在应该,因为它实现了可直接使用作为一个序列的IEnumerable< T> 。在这种情况下自动向上转型实际上做的工作。 :)

 为MyGraph
|> Graph.get_nodes
|> Seq.iter(有趣x  - > printfn%AX)
 

I have a type that is either a Dictionary<string,Node<'a>>*Edge<'a> list or a ConcurrentDictionary<string,Node<'a>>*Edge<'a> list. I am trying to create a get_nodes function, but when I call .Values from the Dictionary and the ConcurrentDictionary, the functions return different types!

So I need to somehow convert both of the types into the same type for F# to compile...

The type given by Dictionary.Values is Dictionary'2.ValueCollection<string,Node<'a>> while the type yielded by ConcurrentDictionary is ICollection<Node<'a>>.

I figured out that both types have a "GetEnumerator()" function. What I need to do is somehow turn the enumerator into a seq or list, etc.

Here is my code:

   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()

How do I pull the data out of the enum variable?

解决方案

You are probably used to C# which would auto upcast the ValueCollection to an ICollection (which ValueCollection implements). F# does not do this, so you must manually cast the result of Dictionary.Values to ICollection.

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

Full method would look something like this:

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

From what I understand, F# does not auto-upcast because of the way that the auto type inference engine works. It's irritating when you're used to C#, but it's a price worth paying to get automatic type inferencing. Also consider that in C#, you would have to specify the return type up front on the method, which makes it easy for C# to do the cast for you. F# engine infers the return type based on what you actually return, so the safest thing is to not make assumptions about how you want it cast.

Not general consensus, but my opinion: I hope they will add auto upcasting of return values for specific cases (like output type is declared ahead of time or to make branches conform like above), but it's a minor irritation for now.

Update (from question in comments)

ICollection<T> should now be directly usable as a sequence since it implements IEnumerable<T>. In this case auto-upcasting actually does work. :)

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

这篇关于转换一个枚举在F#列表或序列或泛型集合类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆