转换一个枚举在F#列表或序列或泛型集合类型 [英] converting an enum to a list or sequence or generic collection type in 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实现)
令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屋!