【问题标题】:Higher order type classes in scalascala中的高阶类型类
【发布时间】:2017-05-16 21:17:33
【问题描述】:

我正在尝试理解类型类,到目前为止,我了解了 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]] 类型,因为我并没有真正处理两个幺半群实例,只有两个类是隐式幺半群,但我不确定如何表达。

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

【问题讨论】:

    标签: scala typeclass


    【解决方案1】:

    Monoid 本身不是一个类型。这是一个类型构造函数,所以Pair[Monoid, Monoid] 没有意义。

    你真正想要的实际上是:假设你有一个Monoid 类型的类实例用于两个给定类型AB,然后也为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]] 的新隐式实例。

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

    其他说明。如果您不喜欢将隐式实例定义为 defval,您可以对隐式类执行相同操作:

    implicit class MonoidPair[A, B](implicit A: Monoid[A], B: Monoid[B]) extends Monoid[Pair[A, B]] {
      ... //same body as before
    }
    

    【讨论】:

    • 非常感谢,它确实为我解决了问题。我想结论是,如果我们需要参数,我们也需要使用带参数的东西,然后返回 Monoid,例如带有 monoid 返回值的 def 或扩展 monoid 特征的类的构造函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2019-06-30
    • 2017-01-01
    • 1970-01-01
    • 2012-11-21
    相关资源
    最近更新 更多