2012-05-24 7 views
11

Ich hatte in C# programmiert, war aber frustriert von den Einschränkungen seines Typsystems. Eines der ersten Dinge, die ich über Scala erfuhr, war, dass Scala höhere Generationsgattungen hat. Aber selbst nachdem ich mir eine Reihe von Artikeln, Blogeinträgen und Fragen angeschaut hatte, war ich mir immer noch nicht sicher, welche höherklassigen Generika es waren. Wie auch immer, ich hatte etwas Scala-Code geschrieben, der in Ordnung war, . Verwendet dieses Snippet höhere Arten?Scala: Höhere Klassen-, Open-Typ- und Wildcard-Generics in Java, C#, Scala und C++

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

Und dann dachte ich, vielleicht schon mit mir höher kinded Generika. Wie ich es verstehe, war ich es, aber dann, als ich es jetzt verstehe, hatte ich bereits glücklichere Typen in C# benutzt, bevor ich überhaupt von Scala gehört hatte. Verwendet dieses Snipet einen höheren Typ?

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

So weitere Verwirrung zu vermeiden Ich dachte, es wäre nützlich für jeden von Java, C# und Scala, was sie in Bezug auf die Höhere kinded Typen, Wildcards und die Verwendung offener/teilweise offenen Typen erlauben zu klären. Der Hauptunterschied zwischen C# und Scala scheint zu sein, dass Scala Platzhalter und offene Typen erlaubt, während C# keine Platzhalter hat und alle generischen Typen vor der Verwendung geschlossen werden müssen. Ich weiß, dass sie etwas anderes sind, aber ich denke, es wäre nützlich, die Existenz dieser Features mit ihrer Entsprechung in C++ - Templates in Beziehung zu setzen.

So ist das Folgende korrekt? Diese Tabelle ist für Alexey Antwort korrigiert

Lang: Higher-kind Wild-card Open-types 

Scala yes   yes  yes 

C#  no   no  no 

Java  no   yes  no 

C++  yes   yes  yes 
+3

Was ist Ihre Frage? –

+0

Ist die Tabelle unten korrekt? Wenn es jemand besser formatieren kann? –

+0

Was Sie in C# geschrieben haben, ist in Java verfügbar, und nicht in Height kinded. Ihre Klasse mit dem obigen GeomT-Parameter ist. Siehe http://stackoverflow.com/a/10499788/754787. –

Antwort

9

Dies ist höher kinded Typ ist es nicht:

Nr Ein höherer kinded Typ ist so etwas wie

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

Ie ein generischer Typ, dessen Parameter selbst generisch sein müssen. Beachten Sie, dass in diesem Beispiel Class1<IList> kompiliert werden sollte, aber Class1<String> oder Class1<IDictionary> sollte nicht.

+0

Ah endlich denke ich, dass ich sehe. –

8

Es scheint, dass Sie verstehen müssen, was höher verbundene Typen sind und warum sie nützlich sind.

Betrachten Sie die folgenden Schnittstellen (Java, F<X,Y> als Verschluss Ersatz verwendet):

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); 
} 

Die Schnittstellen aussehen nützlich, da sie eine Art „Transformation“ für Sammlungen definieren (dies wird als „Funktor“ genannt) . Aber sie sehen ähnlich aus wie Code-Duplizierung. Aber Sie können eine "vereinheitlichte" Schnittstelle weder in Java noch in C# schreiben.

Wie sollte es aussehen? Sie wäre versucht so etwas wie

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

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

Aber X<A> ist nicht in Java oder C# erlaubt zu schreiben, wenn X kein fester Typ wie List, sondern ein Typ Parameter. Aber wenn diese Abstraktion in irgendeiner Weise erlaubt ist (wie in Scala oder Haskell), haben Sie höhere Typen (oder "Polymorphismus höherer Ordnung", die Terminologie ist immer noch unklar).Hier ist die Scala-Eigenschaft und eine Implementierung:

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) 
} 

Das ist die Grundidee. Normalerweise brauchen Sie dieses Zeug nicht zu oft, aber wenn Sie es brauchen, kann es unglaublich nützlich sein.

+0

Erfrischender Vergleich mit Java und C# bezüglich der Typparameter, danke! –