scala中的高阶类型类

时间:2017-05-16 21:17:33

标签: scala typeclass

我正在尝试理解类型类,到目前为止我已经使用了Monoids,这很简单:

object AbstractAlgebra {
  case class Pair[A,B](a: A, b: B)

  trait Monoid[T] {
    def times(t1: T, t2: T): T
    def unit: T
  }
  object Monoid {
    implicit object MonoidIntPlus extends Monoid[Int] {
      def times(i1: Int, i2: Int) = i1 + i2
      def unit = 0
    }
    implicit object StringMonoid extends Monoid[String] {
      def times(s1: String, s2: String) = s1 + s2
      def unit = ""
    }

    implicit object PairOfMonoids extends Monoid[Pair[Monoid, Monoid]] = ???
  }
}

我认为我的问题是类型Monoid [Pair [Monoid,Monoid]],因为我并没有真正处理两个monoid实例,只有两个类是隐式幺半群,但我不知道如何表达它。

任何帮助或参考将不胜感激

1 个答案:

答案 0 :(得分:4)

Monoid本身不是一种类型。它是一种类型构造函数,因此Pair[Monoid, Monoid]毫无意义。

您真正想要的是以下内容:假设您有两个给定类型MonoidA的{​​{1}}类型类实例,那么也为{{1}创建一个实例}}

这可以写成如下(实现是你可以推导出的最自然的实现):

B

这将完全按照我之前的解释:如果找到类型Pair[A, B]implicit def monoidPair[A, B](implicit A: Monoid[A], B: Monoid[B]): Monoid[Pair[A, B]] = new Monoid[Pair[A, B]] { def times(p1: Pair[A, B], p2: Pair[A, B]) = Pair(A.times(p1.a, p2.a), B.times(p1.b, p2.b)) def unit = Pair(A.unit, B.unit) } 的隐式实例,那么它会在范围内放置一个类型为Monoid[A]的新隐式实例。

注意。您的案例类Monoid[B]已在Monoid[Pair[A, B]]中定义(尽管自2.11.0以来已被弃用)Pair[A, B]Predef

其他说明。如果您不想将隐式实例定义为Tuple2[A, B](A, B),则可以对隐式类执行相同操作:

def