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

后端 未结 1 1014
萌比男神i
萌比男神i 2021-01-23 04:44

I have a type that is either a Dictionary>*Edge<\'a> list or a ConcurrentDictionary>*Edge<\

1条回答
  •  盖世英雄少女心
    2021-01-23 05:11

    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>
    

    Full method would look something like this:

    static member get_nodes (g:Graph<'a>) = 
        match g with 
        | Dictionary_Graph(nd,el) ->
            nd.Values :> ICollection>
        | 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 should now be directly usable as a sequence since it implements IEnumerable. In this case auto-upcasting actually does work. :)

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

    0 讨论(0)
提交回复
热议问题