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

Scala: List to List of Lists, idiomatically?

在 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))   

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

额外问题:为什么 Scala 不能推断 lambda 的类型? aList[Int],所以 x 也应该是 List[Int],不是吗?:

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

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

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

headAndSelf(yourList){(h,l) => whatever}