Моноидный экземпляр для ParMap?

Есть ли существующий Monoid экземпляр для scala.collection.parallel.ParMap в кошках? Я так не думаю, но я не уверен.

Если нет, то как бы мне создать такой экземпляр? Вот что у меня так далеко...

import cats._
import implicits._

def parMapMonoid[K, V]: Monoid[ParMap[K, V]] = {
  new Monoid[ParMap[K, V]] {
    def combine(v1: ParMap[K, V], v2: ParMap[K, V]): ParMap[K, V] = {
      ???
    }
    def empty: ParMap[K, V] = {
      ParMap.empty[K, V]
    }
  }
}

... можно предположить, что есть соответствующий Monoid экземпляр, определенный для типа V, Для конкретного случая использования у меня в моем type V=Int,

2 ответа

Решение

Это объединяет значения поточечно, пропущенные значения для ключа k заменены элементом идентичности V-monoid:

def parMapMonoid[K, V](implicit vMon: Monoid[V]): Monoid[ParMap[K, V]] = {
  new Monoid[ParMap[K, V]] {
    def combine(v1: ParMap[K, V], v2: ParMap[K, V]): ParMap[K, V] = {
      val allKeys = v1.keys ++ v2.keys
      (for (k <- allKeys) yield {
        (k, vMon.combine(
          v1.getOrElse(k, vMon.empty),
          v2.getOrElse(k, vMon.empty)
        ))
      })(collection.breakOut)
    }
    def empty: ParMap[K, V] = {
      ParMap.empty[K, V]
    }
  }
}

Так как allKeys также параллельная коллекция, вся конструкция должна быть "разумно распараллелена".

Если вам нужно просто как-то совместить ParMapс, то вы можете просто использовать обычныеMonoid[Map[_, _]], Нет, к сожалению, вы не можете с ParMap не является подтипом Map, Но если вы хотите использовать идеологические FP, вы должны избегать таких структур, как ParMap так как они смешивают описание данных и модель исполнения.

Другие вопросы по тегам