C# generics: is it possible to infer associated types?

D

Dietmar Kuehl

Hi,

after reading the documentation on C# generics from several sources, I'm
still unclear whether it is possible to infer associated types from a
type argument. For example, if I have an enumerator or iterator for a
sequence passed to a generic function, is it possible to arrange things
such that the element type of the underlying sequence can be inferred?

Inferring associated types from type arguments becomes necessary as soon
as you are doing more than absolutely trivial stuff like the ubiquitous
stack example. A simple concrete example is a function which given an
enumerator and a predicate returns the enumerator when the predicate
yields true fo the element:

public interface Enumerator<T> {
public T next();
}
public interface Predicate<T> {
public bool test(T val);
}

public class algos {
public static E find<E, P>(E enumerator, P predicate)
where E: Enumerator<S>
where P: Predicate<T>
{
S tmp = null
do
tmp = enumerator.next();
while (tmp != null && !predicate.text(tmp))
return enumerator;
}
}

The essential portion in this example is that the type parameters 'S' and
'T' can be inferred from the type parameters 'E' and 'P': otherwise it is
impossible to spell out the constraints for 'E' and 'P' to have a 'next()'
and a 'test()' function, respectively. The type returned from 'next()' and
the type expected by 'test()' are potentially different because 'T' can be
a base class of 'S' to make the algorithm still applicable.

The above code uses a syntax I have made up because I haven't seen it in
this form anywhere (which doesn't mean that it isn't described somewhere):
Essentially, the constraints are used for two purposes. On the one hand,
they spell out the expected interfaces of the two parameters. On the other
hand, they are used to infer the types 'S' and 'T': 'S' is the element
type of the sequence iterated over by 'E' and 'T' is the type the
predicate operates on. Whether the notation I used or something else is
used I don't care at all. However, I do care about the possibility to
infer associated types.
 
D

Dietmar Kuehl

Kuba said:
C# for now doesn't support templates :(

Yes, but apparently a specification on generics for C# and the CLR is
already on its way. I have seen some of the stuff coming up but it
seems to be substantially restricted. If so, maybe it is not too late
to change things.
 
A

andrew queisser

The question, which I can't get my head around, is whether
directly specifying S and T as type parameters would work.
If that works it seems like inferring S and T from E and P is
a task for the C# compiler writers and not fundamentally
incompatible with the proposed generics support in .NET.

The example would then look like this:

public interface Enumerator<T> {
public T next();
}
public interface Predicate<T> {
public bool test(T val);
}
public class algos {
public static E find<E, P, S, T>(E enumerator, P predicate)
where E: Enumerator<S>
where P: Predicate<T>
{
S tmp = null
do
tmp = enumerator.next();
while (tmp != null && !predicate.text(tmp))
return enumerator;
}
}

Would this work or not?

Thanks,
Andrew
 
E

Eric Gunnerson [MS]

Please ask on the language message board at

http://msdn.microsoft.com/vcsharp/team/language/default.aspx

--
Eric Gunnerson

Visit the C# product team at http://www.csharp.net
Eric's blog is at http://blogs.gotdotnet.com/ericgu/

This posting is provided "AS IS" with no warranties, and confers no rights.
andrew queisser said:
The question, which I can't get my head around, is whether
directly specifying S and T as type parameters would work.
If that works it seems like inferring S and T from E and P is
a task for the C# compiler writers and not fundamentally
incompatible with the proposed generics support in .NET.

The example would then look like this:

public interface Enumerator<T> {
public T next();
}
public interface Predicate<T> {
public bool test(T val);
}
public class algos {
public static E find<E, P, S, T>(E enumerator, P predicate)
where E: Enumerator<S>
where P: Predicate<T>
{
S tmp = null
do
tmp = enumerator.next();
while (tmp != null && !predicate.text(tmp))
return enumerator;
}
}

Would this work or not?

Thanks,
Andrew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top