我的类型是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>>
如何从枚举变量中提取数据?
答案 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)