gpt4 book ai didi

Scala Monoid[Map[A,B]]

转载 作者:行者123 更新时间:2023-12-04 11:44:44 25 4
gpt4 key购买 nike

我正在阅读一本书,内容如下:

sealed trait Currency
case object USD extends Currency
... other currency types

case class Money(m: Map[Currency, BigDecimal]) {
... methods defined
}

讨论继续识别 Money 上的某些类型的操作。因为是 Monoidal 所以我们要创建一个 MonoidMoney .但是接下来是我无法正确解析的列表。

首先是 zeroMoney的定义.这是按如下方式完成的:
final val zeroMoney: Money = Money(Monoid[Map[Currency, BigDecimal]].zero)

我在这里遇到的问题是 Money 里面的部分参数列表。具体来说
Monoid[Map[Currency, BigDecimal]].zero

这是应该构造什么吗?到目前为止,在讨论中还没有实现 zero Monoid[Map[A,B]] 的函数那么这是什么意思?

以下是以下内容:
implicit def MoneyAdditionMonoid = new Monoid[Money] {
val m = implicitly(Monoid[Map[Currency, BigDecimal]])
def zero = zeroMoney
def op(m1: Money, m2: Money) = Money(m.op(m1.m, m2.m))
}
op的定义考虑到其他一切都很好,所以这不是问题。但是我还是不明白是什么 zeroMoney给出了它的定义。这也给我带来了与隐式 m 相同的问题以及。

那么, Monoid[Map[Currency, BigDecimal]] 到底是做什么的?其实呢?自 Monoid 以来,我看不到它是如何构造任何东西的是一个没有实现的特征。不定义怎么用 opzero第一的?

最佳答案

要编译此代码,您需要如下内容:

trait Monoid[T] {
def zero: T
def op(x: T, y: T): T
}

object Monoid {
def apply[T](implicit i: Monoid[T]): Monoid[T] = i
}

所以 Monoid[Map[Currency, BigDecimal]].zero脱糖成 Monoid.apply[Map[Currency, BigDecimal]].zero ,简化为 implicitly[Monoid[Map[Currency, BigDecimal]]].zero .
zero在 Monoidal 上下文中是这样的元素
Monoid[T].op(Monoid[T].zero, x) ==
Monoid[T].op(x, Monoid[T].zero) ==
x

Map的情况下,我会假设 Monoid结合 map 与 ++ . zero然后就是 Map.empty ,这是什么 Monoid[Map[Currency, BigDecimal]].zero最后简化为。

编辑:回答 comment :

请注意,这里根本没有使用隐式转换。这是仅使用隐式参数的类型类模式。

Map[A, B] is a Monoid if B is a Monoid



这是一种方法,与我用 ++ 建议的方法不同。 .让我们看一个例子。您希望以下 map 如何组合在一起:?
  • Map(€ → List(1, 2, 3), $ → List(4, 5))
  • Map(€ → List(10, 15), $ → List(100))

  • 您期望的结果可能是 Map(€ → List(1, 2, 3, 10, 15), $ → List(4, 5, 11)) ,这是唯一可能的,因为我们知道如何组合两个列表。 Monoid[List[Int]]我在这里隐式使用的是 (Nil, :::) .通用型 B你还需要一些东西来粉碎两个 B一起,这个东西叫做 Monoid !

    为了完整起见,这里是 Monoid[Map[A, B]]我猜这本书想要定义:
    implicit def mm[A, B](implicit mb: Monoid[B]): Monoid[Map[A, B]] =
    new Monoid[Map[A, B]] {
    def zero: Map[A, B] = Map.empty

    def op(x: Map[A, B], y: Map[A, B]): Map[A, B] =
    (x.toList ::: y.toList).groupBy(_._1).map {
    case (k, v) => (k, v.map(_._2).reduce(mb.op))
    }.toMap
    }

    关于Scala Monoid[Map[A,B]],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42600662/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com