bsd*_*ish 6 functional-programming scala list-manipulation
我知道map函数接受列表的每个元素(一个序列)并将一个函数应用于它.递归(并且不考虑终止条件等)
map(s, f) = f(s.head) :: map(s.tail, f)
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个像这样的功能
foo(s, f) = f(s) :: map(s.tail, f).
Run Code Online (Sandbox Code Playgroud)
所以'mapper'是在子列表而不是单个元素上调用映射函数的地方.在lisp术语中,我正在寻找一个地图列表,而不是mapcar.这样的事情是存在的,还是我必须自己滚动(或使用递归)?
或者,我将采用一个函数,将序列作为输入,并返回一系列中到端子序列,即
bar(s, f) = s :: bar(s.tail, f)
Run Code Online (Sandbox Code Playgroud)
/*这种方法根据另一种称为tails的有用方法定义了mapList.像丹尼尔一样,我会把它放在List的隐含扩展中,但这纯粹是一种品味*/
implicit def richerList[A](list : List[A]) = new {
Run Code Online (Sandbox Code Playgroud)
/*这是一个名为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
}
Run Code Online (Sandbox Code Playgroud)
/*这就是使用tails的样子
scala> "abc".toList.tails
res0: List[List[Char]] = List(List(a, b, c), List(b, c), List(c))
Run Code Online (Sandbox Code Playgroud)
*/
/*现在我们可以根据尾部定义mapList*/
def mapList[B](f : List[A] => B) = tails map f
}
Run Code Online (Sandbox Code Playgroud)
/*这就是使用mapList的样子
scala> "abc".toList mapList (_.reverse.mkString)
res1: List[String] = List(cba, cb, c)
Run Code Online (Sandbox Code Playgroud)
*/