多重集的高级类型

Higher-kinded types for multisets

我想在 Scala 中写一个 Multiset[T, S[_]] class,它有两个类型参数:T 是元素的类型,而 S 是集合的底层表示。 在这个多重集中,构造了 S[(T, Int)] 的一个实例(在每一对中,T 是元素,Int 是它的出现次数)。 这在 C++ 中是可能的:

template<typename T, template<typename> S>

两个问题:

第一个问题:请改用S[X] <: Set[X]。使用下划线标记高阶类型参数很方便,不需要用无用的名字来引起注意,但实际上你可以使用任何标识符。对于这种特殊情况,下划线不起作用。你甚至可以做 S[X] <: Set[List[X]] 这样的事情。

第二个问题:没有直接等价物,但是我很少在C#中使用它,因为它意味着对象只能由无参数构造函数创建,这是一个很大的限制,在强制所有可能使用您的代码。 class 的用户可能喜欢在初始化时设置容量,或者使用池等等。大多数时候,我在构造函数中需要一个 Func<S> 委托,并且我可能会添加一个静态工厂,它接受 new 作为方便,如

class Generic<T> 
{
   public Generic(..., Func<T> factory)
}

static class Generic 
{
  public Generic<T> Create(....) where T : new {
    return new Generic(..., () => new T());
  }
}

在scala中,你需要传递函数。一种可能的替代方法是使用隐式参数,例如

trait Builder[A] {
   def build(): A
}

object Builder {
  def build[A: Builder] : A = implicitly[Builder[A]].build()
}

class Generic[A: Builder](....) {....
    ...
    // instead of val a = new A()
    val a = Builder.build[A]
    ....
}

那么您只需确保构建器在您的参数类型的隐式范围内可用,默认情况下将使用它。当默认的不是你想要的时,你仍然可以显式地传递另一个。