我知道map函数接受列表(序列)的每个元素并对其应用一个函数。递归(且不考虑终止条件等)
map(s, f) = f(s.head) :: map(s.tail, f)
我正在寻找一个功能类似于
foo(s, f) = f(s) :: map(s.tail, f).
因此是一个“映射器”,其中映射函数在子列表而不是单个元素上被调用。简而言之,我正在寻找的是地图列表,而不是mapcar。是否存在类似的内容,还是我必须自己滚动(或使用递归)?
或者,我将采用一个函数作为输入,并返回中端子序列的序列,即
bar(s, f) = s :: bar(s.tail, f)
最佳答案
/ *此方法根据另一个称为tails的有用方法来定义mapList。像Daniel一样,我会将其放在List的隐式扩展中,但这纯粹是一个品味问题* /
implicit def richerList[A](list : List[A]) = new {
/ *这是一个称为tails的方法,该方法返回列表中的每个可能的尾巴。它是尾递归的,因此不会在大列表上爆炸。请注意,它与同名的Haskell函数略有不同。 Haskell版本始终在结果上添加一个空列表* /
def tails : List[List[A]] = {
def loop(ls : List[A], accum : List[List[A]]) : List[List[A]] = ls match {
case _ :: tail => loop(tail, ls :: accum)
case _ => accum
}
loop(list, Nil).reverse
}
/ *这是使用尾巴的样子
scala> "abc".toList.tails
res0: List[List[Char]] = List(List(a, b, c), List(b, c), List(c))
* /
/ *现在我们可以基于尾部定义mapList * /
def mapList[B](f : List[A] => B) = tails map f
}
/ *这就是使用mapList的样子
scala> "abc".toList mapList (_.reverse.mkString)
res1: List[String] = List(cba, cb, c)
* /