2010-05-14 16 views
2

J'ai un très grand List[A] et une fonction f: List[A] => List[B]. Je voudrais divisé ma liste originale en sous-listes avec une taille maximale, appliquez la fonction à chaque sous-liste à tour de rôle, puis non divisé le résultat en un grand List[B]. Ce assez facile:Scalaz fractionnement d'un calcul en sous-parties

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(_))) 
} 

Je me demandais si scalaz fourni des trucs standard pour faire de la boîte? En particulier la méthode apply?

Répondre

3

unsplit juste MA#join, pour tout M[M[A]]M est un Monad.

split n'existe pas en dehors de la boîte. Ce qui suit est un tour sur la façon de le faire, plus pour démontrer quelques concepts Scalaz. Il déclenche actuellement un débordement de pile dans le compilateur pour le moment!

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 
+0

Le problème est que mon 'f' est un' M [A] => M [B] ': je ne vois rien dans scalaz qui puisse aider avec ça (je vois seulement des choses comme' A => M [B] ',' M [A => B] 'etc) –

+0

' val f: Liste [A] => Liste [B] = ...; (carte groupée f joindre): Liste [B] ' – retronym

1

Que diriez-vous ceci:

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) 
+0

Eh bien, erm, oui. J'ai dit que c'était facile - j'ai demandé si Scalaz avait quelque chose pour réaliser ceci hors de la boîte (probablement généralisé sur d'autres monades) –

+0

Je dirais que ls.grouped (max) est aussi succinct que split (ls, max) –