Scala:列举到列表列表,惯用?

时间:2016-03-07 18:18:24

标签: scala scala-collections

在Scala中,我编写了一个高阶函数,它迭代一个列表,并使用头部和列表回调每个元素,即:

  def headAndSelf[A, B](li: List[A], f: (A, List[A]) => B): List[B] = { 
    if (li == Nil) Nil
    else f(li.head, li) :: headAndSelf(li.tail, f)
  }

给定val a = List(1,2,3)

scala> headAndSelf(a, (x: Int, y: List[Int]) => (x,y))
res4: List[(Int, List[Int])] = List((1,List(1, 2, 3)), (2,List(2, 3)), (3,List(3))) 

然后我发现我可以从列表中找到头部,所以写起来更简单:

  def self[A, B](li: List[A], f: (List[A]) => B): List[B] = { 
    if (li == Nil) Nil
    else f(li) :: self(li.tail, f)
  }

(即使它使lambda不那么优雅)

scala> self(a, (x: List[Int]) => x)
res7: List[List[Int]] = List(List(1, 2, 3), List(2, 3), List(3))   

然后我想,肯定有一种更简单,惯用的方式将List转换为列表列表。那是什么?

奖金问题:为什么Scala不能推断lambda的类型? aList[Int],因此x也应该是List[Int],不是吗?:

scala> self(a, x => x)
<console>:13: error: missing parameter type
       self(a, x => x)
               ^      

1 个答案:

答案 0 :(得分:4)

int *x = (int *)malloc(sizeof(int)); int *y = (int *)malloc(sizeof(int)); int *l = (int *)malloc(sizeof(int)); int *m = (int *)malloc(sizeof(int)); settings(x,y,l,m); 将完成大部分工作。

tails将有一个空列表作为其最后一个元素,您需要对其进行过滤,这是tails下面的内容:

collect

如此处所示,有两个参数列表将允许正确的类型推断。您在呼叫站点也需要两个列表,但这通常很方便:

def headAndSelf[A,B](l: List[A])(f: (A, List[A]) => B) = 
  l.tails.collect{case list @ head :: _ => f(head, list)}.toList