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# 中是不允许的,如果X不是像 那样的固定类型List,而是类型参数。但是,如果以某种方式允许这种抽象(例如在 Scala 或 Haskell 中),那么您将拥有更高种类的类型(或“高阶类型多态性”,术语对此仍然模糊不清)。这是 Scala 特征和实现:

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 回答