robkuz
robkuz

Reputation: 9934

How to define a generic function and its return parameter

I am struggling with a seeming trivial problem concerning generics.

I have these methods

 let toTypedCollection r l = 
     l |> List.iter (fun x -> r.Add(x)
     r
 let toRowDefinitions = toTypedCollection (new RowDefinitionCollection())
 let toColsDefinitions = toTypedCollection (new ColumnDefinitionCollection())

where

public sealed class ColumnDefinitionCollection : DefinitionCollection<ColumnDefinition>

and

public sealed class RowDefinitionCollection : DefinitionCollection<RowDefinition>

Now I get an compiler error telling me that r.Addneeds to be augmented with type information. So I do this

let toTypedCollection (r:DefinitionCollection<_>) l = ...

The problem now however is that the resulting signature for toRowDefinitions looks like

DefinitionCollection<RowDefiniton> -> list RowDefinition -> DefinitionCollection<RowDefinition>

That is all fine - except for the return type. I absolutely need to have a RowDefinitonCollection instead of DefinitionCollection<RowDefinition>

Has anybody an idea on how to accomplish this?

Upvotes: 0

Views: 92

Answers (2)

scrwtp
scrwtp

Reputation: 13577

Try let toTypedCollection<'T> (r: #DefinitionCollection<'T>) l = ....

The # solves the problem for me on a simple sample, though you might need to annotate toRowDefinitions/toColsDefinitions to pin down the exact return types as well.

Upvotes: 2

Vandroiy
Vandroiy

Reputation: 6223

I think you are looking for something like this:

let toTypedCollection (r : 'T when 'T :> ICollection<_>) l = 
    l |> List.iter (fun x -> r.Add(x))
    r

where ICollection<_> is the one from System.Collections.Generic, but of course, you could use DefinitionCollection<_> if you need the concrete type.

scrwtp's answer shows a shorter notation to achieve a similar type annotation without naming 'T: Instead of 'T when 'T :> ICollection<_>, you can also write #ICollection<_>. In this case, 'T isn't used elsewhere, so this notation is shorter.

There is also the less type-safe way of making toTypedCollection inline and adding a static member constraint that r needs an Add method; but with that, it would work on any type with an Add method, which usually isn't a good idea.

Upvotes: 1

Related Questions