如何为Scala中的泛型类型提供默认的类型类? [英] How to provide a default typeclass for generic types in Scala?

查看:177
本文介绍了如何为Scala中的泛型类型提供默认的类型类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 Strings under the concatenation operation form a monoid, we can provide a default monoid for Strings 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆