如何为Scala中的泛型类型提供默认的类型类? [英] How to provide a default typeclass for generic types in Scala?
问题描述
Monoid [T]
,你可以为不同类型的monoids提供许多默认类型类实现。 假设monoid被定义为:
pre $ trait Monoid [T ] {
def op(x:T,y:T):T
def id:T
}
由于连接操作下的字符串
s形成一个monoid,我们可以为 String
s像这样:
隐式对象StringMonoid extends Monoid [String] {
override def op (a:String,b:String):String = a + b
覆盖def id:String =
}
这很简单,因为 String
不是泛型类型。
我要求的是如何为 Seq [T]
s提供一个默认monoid。 / strong>,其中type参数阻止我像上面那样创建隐式对象。
我可以这样做:
class SeqMonoid [T]扩展Monoid [Seq [T]] {
覆盖def op(a:Seq [T],b:Seq [T]) :Seq [T] = a ++ b
override def id:Seq [T] = Nil
}
隐式对象intSeqMonoid extends SeqMonoid [Int]
隐式对象doubleSeqMonoid extends SeqMonoid [Double]
隐式对象stringSeqMonoid extends SeqMonoid [String]
...
但这种方法不利用泛型类型的美。
所以,一般来说,我的问题是:Scala中是否有任何方法可以为泛型类型提供类型类实现?
您可以使用所需的类型提供隐式函数:
implicit def SeqMonoid [T]:Monoid [Seq [T]] = new Monoid [Seq [T]] {
override def op(a:Seq [T],b:Seq [T ]):Seq [T] = a ++ b
override def id:Seq [T] = Nil
}
In Scala, if you create a typeclass, say the algebraic structure Monoid[T]
, you can provide many default typeclass implementations for different types that are monoids.
Suppose a monoid is defined as:
trait Monoid[T] {
def op(x: T, y: T): T
def id: T
}
Since String
s under the concatenation operation form a monoid, we can provide a default monoid for String
s like this:
implicit object StringMonoid extends Monoid[String] {
override def op(a: String, b: String): String = a + b
override def id: String = ""
}
This is rather easy, since String
is not a generic type.
What I am asking for is how to provide a default monoid for Seq[T]
s, in which the type parameter prevents me from creating an implicit object like I did above.
I could do:
class SeqMonoid[T] extends Monoid[Seq[T]] {
override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b
override def id: Seq[T] = Nil
}
implicit object intSeqMonoid extends SeqMonoid[Int]
implicit object doubleSeqMonoid extends SeqMonoid[Double]
implicit object stringSeqMonoid extends SeqMonoid[String]
...
But this approach doesn't utilize the beauty of generic types.
So, in general, my question is: Is there any way in Scala I can provide typeclass implementations for generic types?
You can provide an implicit function with the required type:
implicit def SeqMonoid[T]: Monoid[Seq[T]] = new Monoid[Seq[T]] {
override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b
override def id: Seq[T] = Nil
}
这篇关于如何为Scala中的泛型类型提供默认的类型类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!