【问题标题】:How to combine arrays of monoid type?如何组合幺半群类型的数组?
【发布时间】:2017-03-07 13:03:57
【问题描述】:

幺半群类型A 的列表或数组也是一个幺半群。现在我想combine 使用cats 的整数数组。

scala> 1 |+| 2
res1: Int = 3

scala> Array(1, 2, 3) |+| Array(1, 2, 3)
<console>:21: error: value |+| is not a member of Array[Int]
   Array(1, 2, 3) |+| Array(1, 2, 3)

我想得到Array(2, 4, 6) 作为Array(1, 2, 3) |+| Array(1, 2, 3) 的结果。我该怎么做?

【问题讨论】:

  • 这并不是|+| 的真正用途。这意味着是一个追加操作。如果数组大小不同会怎样?
  • 幺半群类型 A 的列表或数组也是一个幺半群 这是理论上的,但您需要在代码中实际提供 Monoid[Array],例如通过implicit
  • @MichaelZajac 谢谢。我可能错了。一个幺半群数组可能不是一个幺半群。
  • 请注意,Scalaz 中有一个名为 merge 的操作完全符合您的要求:github.com/scalaz/scalaz/blob/… 我认为,他们只是还没有将其移植到 cats
  • @Michael 我已经检查过但没有找到 :( 另外,我没有找到 ArrayMonoid 实例。

标签: arrays scala monoids scala-cats


【解决方案1】:

SeqArray 上的combine 通常意味着附加它们以创建新集合。

但是,您可以通过定义自己的Monoid 来做您想做的事情,使用zip 而不是append。这是我临时想到的:

implicit val zipArrayMonoid = new Monoid[Array[Int]] {
  override def combine(x: Array[Int], y: Array[Int]) = {
    x.zip(y).map {
      case (a, b) => a + b
    }
  }

  override def empty = Array.empty
}

这将导致不同大小的数组的附加值被忽略(正如zip 实现所做的那样,您可以查看文档here

这是一个带有结果的 scalaFiddle:https://scalafiddle.io/sf/YzdUl4L/0

【讨论】:

  • 谢谢!但是如果数组大小不同怎么办?
  • 该实例违反了每一个幺半群定律。
  • 确实如此,但我不知道如何在不违反它们的情况下为他的用例实现 Monoid 实例。
猜你喜欢
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多