2010-05-14 61 views
2

我有一个非常大的List[A]和函数f: List[A] => List[B]。我想将分割为将我原来的列表分成最大大小的子列表,依次将这个函数应用到每个子列表中,然后将非分割的结果合并成一个大的List[B]。这很简单:斯卡拉斯分裂计算分部分

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

我想知道scalaz是否提供标准的东西要做到这一点开箱?特别是apply方法?

回答

3

unsplit它只是MA#join,对于任何M[M[A]]其中MMonad

split开箱即用不存在。以下是关于这样做的一个方面,更多的是展示一些Scalaz概念。它现在实际上触发了编译器中的堆栈溢出!

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

麻烦的是我的'f'是'M [A] => M [B]':我在scalaz中看不到任何东西可以帮助解决这个问题(我只看到像A => M [B] ''''M [A => B]'等) – 2010-05-14 15:17:35

+0

'val f:List [A] => List [B] = ...; (分组映射f join):列出[B]' – retronym 2010-05-14 15:26:10

1

如何:

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

恩,恩,是的。我说这很容易 - 我问斯卡拉茨是否有什么可以实现这个开箱即用(可能推广到其他单子) – 2010-05-14 11:02:25

+0

我想说ls.grouped(max)就像分裂(ls,max)一样简洁 – 2010-05-14 15:28:40