2012-05-24 30 views
11

He estado programando en C#, pero estaba frustrado por las limitaciones de su sistema de tipos. Una de las primeras cosas que aprendí sobre Scala fue que Scala tiene genéricos de mayor calidad. Pero incluso después de haber analizado una serie de artículos, entradas de blog y preguntas, todavía no estaba seguro de cuáles eran los genéricos de mayor calidad. De todos modos, había escrito un código Scala que compilaba bien, ¿Este fragmento utiliza tipos superiores?Scala: genéricos de tipo kinded, open-type y wild más altos en Java, C#, Scala y C++

abstract class Descrip [T <: DTypes, GeomT[_ <: DTypes] <: GeomBase[_]](newGeom: NewGeom[GeomT]) 
{ 
    type GeomType = GeomT[T] 
    val geomM: GeomT[T] = newGeom.apply[T]() 
} 

Y entonces pensé que tal vez ya estoy usando genéricos más alta kinded. Como yo lo entiendo, lo estaba, pero entonces, como ahora lo entiendo, ya había estado felizmente usando tipos de mayor kínder en C# antes de siquiera haber escuchado sobre Scala. ¿Utiliza este snipet un tipo más alto de kinded?

namespace ConsoleApplication3 
{ 
    class Class1<T> 
    { 
     List<List<T>> listlist; 
    } 
} 

Así que para evitar más confusión que pensé que sería útil aclarar a cada una de Java, C# y Scala lo que permiten en términos de mayor kinded tipos, comodines y el uso de tipos de apertura/parcialmente abiertas. Como la diferencia clave entre C# y Scala parece ser que Scala admite comodines y tipos abiertos, mientras que C# no tiene comodín y requiere que todos los tipos genéricos se cierren antes de su uso. Sé que son algo diferente, pero creo que sería útil relacionar la existencia de estas características con su equivalente en las plantillas de C++.

¿El siguiente es correcto? Esta tabla se ha corregido la respuesta de Alexey

Lang: Higher-kind Wild-card Open-types 

Scala yes   yes  yes 

C#  no   no  no 

Java  no   yes  no 

C++  yes   yes  yes 
+3

¿Cuál es tu pregunta? –

+0

¿Es correcta la tabla de abajo? Si alguien puede formatearlo mejor, ¿por qué no? –

+0

Lo que ha escrito en C# está disponible en java, y no en Kinder más alto. Tu clase con el parámetro GeomT arriba es. Ver http://stackoverflow.com/a/10499788/754787. –

Respuesta

9

Esto es más alto tipo kinded no es así:

No. Un tipo kinded superior es algo así como

class Class1<T> 
{ 
    T<String> foo; // won't compile in actual C# 
} 

Es decir un tipo genérico cuyos parámetros deben ser genéricos. Tenga en cuenta que en este ejemplo Class1<IList> debe compilar, pero Class1<String> o Class1<IDictionary> no debería.

+0

Ah, finalmente creo que veo. –

8

Parece que necesita comprender qué tipos de par superior son, y por qué son útiles.

considerar las siguientes interfaces (Java, F<X,Y> utilizará como reemplazo de cierre):

interface ListFun { 
    public <A,B> List<B> fmap(F<A,B> fn, List<A> list); 
} 

interface SetFun { 
    public <A,B> Set<B> fmap(F<A,B> fn, Set<A> set); 
} 

Las interfaces se ven útil, ya que definen una especie de "transformación" para las colecciones (esto se llama un "funtor") . Pero se parecen mucho a la duplicación de código. Pero no puede escribir una interfaz "unificada", ni en Java ni en C#.

¿Cómo debería ser? Usted sería tentado a escribir algo como

interface Fun<X> { 
    public <A,B> X<B> fmap(F<A,B> fn, X<A> col); 
} 

class ListFun implements Fun<List> {...} 

Pero X<A> no está permitido en Java o C#, si X no es un tipo fijo como List, pero un parámetro de tipo . Pero si esta abstracción está permitida de alguna manera (como en Scala o Haskell), tienes tipos de kinded más altos (o "polimorfismo de tipo de orden superior", la terminología es aún turbia para esto).Aquí es el rasgo Scala y una implementación:

trait Fun[X[_]] { 
    def fmap[A,B](fn: A => B, col:X[A]):X[B] 
} 

class ListFun extends Fun[List]{ 
    def fmap[A,B](fn: A => B, list: List[A]) = list.map(fn) 
} 

Esa es la idea básica. Normalmente no necesita esto con demasiada frecuencia, pero cuando lo necesita, puede ser increíblemente útil.

+0

Refrescante comparación con java y C# con respecto a los parámetros de tipo, ¡gracias! –