Scalaz dividindo um cálculo em sub-partes
-
26-09-2019 - |
Pergunta
Eu tenho um muito grande List[A]
e uma função f: List[A] => List[B]
. Eu gostaria de dividir Minha lista original em sub-listas com tamanho máximo, aplique a função a cada sublista por sua vez e depois não explite o resultado em um grande List[B]
. Isso é bem fácil:
def split[T](l : List[T], max : Int) : List[List[T]] = //TODO
def unsplit[T](l : List[List[T]]) : List[T] = //TODO
def apply[A, B](l : List[A], f : List[A] => List[B], max : Int) : List[B] = {
unsplit(split(l, max).map(f(_)))
}
Eu queria saber se scalraz Forneceu material padrão para fazer isso fora da caixa? Em particular o apply
método?
Solução
unsplit
é só MA#join
, para qualquer M[M[A]]
Onde M
é um Monad
.
split
não existe fora da caixa. A seguir, é apresentada uma maneira de fazer isso, mais para demonstrar alguns conceitos de Scalaz. Na verdade, ele desencadeia um excesso de pilha no compilador no momento!
val ls = List(1, 2, 3, 4, 5)
val n = 5
def truesAndFalses(n: Int): Stream[Boolean] =
Stream.continually(true.replicate[Stream](n) |+| false.replicate[Stream](n)).join
val grouped: List[List[Int]] = {
var zipped: List[(Int, Boolean)] = ls.zip(truesAndFalses(2))
var groupedWithBools: List[List[(Int, Boolean)]] = zipped splitWith {_._2}
groupedWithBools ∘∘ {pair: (Int, _) => pair._1}
}
val joined: List[Int] = grouped ∘∘ {_ * 2} join
Outras dicas
Que tal agora:
def split[T](ls: List[T],max: Int): List[List[T]] = ls.grouped(max).toList
def unsplit[T](ls: List[List[T]]): List[T] = ls.flatMap(identity)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow