11

私はC#でプログラミングしてきましたが、その型システムの制限に不満を感じていました。私がScalaについて最初に知ったのは、Scalaにはより高い種類のジェネリックが含まれているということでした。しかし、多くの記事、ブログエントリ、質問を調べた後でも、より高種類のジェネリックが何であるかはわかりませんでした。とにかく、私はうまくコンパイルされたいくつかのScalaコードを書きました、このスニペットはより高い種類を使用しますか?

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

そして、多分私はすでにより高い種類のジェネリックを使用していると思いました。私はそれを理解していましたが、今ではそれを理解しているので、Scalaのことを聞く前に、C#でより高い種類の型をすでに喜んで使用していました。このスニペットはより高い種類のタイプを使用していますか?

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

したがって、さらなる混乱を避けるために、Java、C#、Scalaのそれぞれについて、より高い種類の型、ワイルドカード、およびオープン/部分的にオープンな型の使用に関して、それらが何を許可するかを明確にすることが役立つと思いました。C#とScalaの主な違いは、Scalaではワイルドカードとオープンタイプが許可されているようですが、C#にはワイルドカードがなく、使用する前にすべての汎用タイプを閉じる必要があります。それらは多少異なることは知っていますが、これらの機能の存在をC++テンプレートの同等の機能に関連付けると便利だと思います。

それで、次は正しいですか?この表は、Alexeyの回答に合わせて修正されています

Lang:   Higher-kind Wild-card Open-types

Scala    yes         yes       yes

C#       no          no        no

Java     no          yes       no

C++      yes         yes       yes
4

2 に答える 2

9

これはより親切なタイプですが、そうではありません:

いいえ。種類の多いタイプは次のようなものです。

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

つまり、パラメータ自体がジェネリックである必要があるジェネリック型です。この例Class1<IList>ではコンパイルする必要がありますが、コンパイルしClass1<String>ないClass1<IDictionary>でください。

于 2012-05-24T14:05:52.323 に答える
8

高種類のタイプとは何か、なぜそれらが役立つのかを理解する必要があるようです。

次のインターフェース(Java、F<X,Y>クロージャーの置換として使用)を検討してください。

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

インターフェースは、コレクションの一種の「変換」(これは「ファンクター」と呼ばれます)を定義するため、便利に見えます。しかし、それらはコードの重複とほとんど同じように見えます。ただし、JavaでもC#でも、「統一された」インターフェイスを作成することはできません。

それはどのように見えるべきですか?あなたは次のようなものを書きたくなるでしょう

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

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

ただし、がのような固定型ではなく、型パラメータX<A>である場合、JavaまたはC#では許可されません。しかし、この抽象化が何らかの方法で許可されている場合(ScalaやHaskellのように)、より高い種類の型があります(または、「より高次の型のポリモーフィズム」、この用語はまだ曖昧です)。Scalaの特性と実装は次のとおりです。XList

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

それが基本的な考え方です。通常、このようなものはあまり必要ありませんが、必要な場合は非常に便利です。

于 2012-05-24T21:24:29.397 に答える