Scala 中惯用的 Haskell-like 迭代?
Idiomatic Haskell-like iterate in Scala?
在Haskell中,我可以通过调用获得无限的顺序函数应用程序列表:
iterate :: (A -> A) -> A -> [A]
假设在 scala 中我有 f(x: A): A
。是否有一个函数会产生一系列顺序函数应用程序?喜欢 iter(f: A => A, x: A): Stream[A]
?
有Iterator.iterate
and Stream.iterate
():
Stream.iterate(1)(_ + 1)
或者你可以自己写一个,使用 Stream
:
def iter[A](f: A => A, x: A): Stream[A] = {
val result = f(x)
result #:: iter(f, result)
}
(请注意,按住 Stream
会导致记忆问题 warned about in the documentation)。使用它很简单:
scala> iter[Int](_ + 1, 1).iterator.drop(100 * 100 * 100).take(10).toList
res1: List[Int] = List(1000002, 1000003, 1000004, 1000005, 1000006, 1000007, 1000008, 1000009, 1000010, 1000011)
是的,已经在图书馆了:Iterator.iterate
Iterator.iterate(1)(_ + 1).drop(100 * 100 * 100).take(10).toList
//> List(1000001, 1000002, 1000003, 1000004, 1000005,
1000006, 1000007, 1000008, 1000009, 1000010)
与@Sean Vieira 的基本相同,具有更多类似于 Haskell 的语法:
scala> def iterate[A]: (A => A) => A => Stream[A] = {
| f => x => x #:: iterate(f)(f(x))
| }
iterate: [A]=> (A => A) => (A => Stream[A])
scala> iterate[Int](_+1)(1) take 10 toList
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
交换f
和x
的位置可以帮助编译器:
scala> def iterate[A]: A => (A => A) => Stream[A] = {
| x => f => x #:: iterate(f(x))(f)
| }
iterate: [A]=> A => ((A => A) => Stream[A])
scala> iterate(1)(2+) take 10 toList //Don't need to use iterate[Int] here
res3: List[Int] = List(1, 3, 5, 7, 9, 11, 13, 15, 17, 19)
在Haskell中,我可以通过调用获得无限的顺序函数应用程序列表:
iterate :: (A -> A) -> A -> [A]
假设在 scala 中我有 f(x: A): A
。是否有一个函数会产生一系列顺序函数应用程序?喜欢 iter(f: A => A, x: A): Stream[A]
?
有Iterator.iterate
and Stream.iterate
(
Stream.iterate(1)(_ + 1)
或者你可以自己写一个,使用 Stream
:
def iter[A](f: A => A, x: A): Stream[A] = {
val result = f(x)
result #:: iter(f, result)
}
(请注意,按住 Stream
会导致记忆问题 warned about in the documentation)。使用它很简单:
scala> iter[Int](_ + 1, 1).iterator.drop(100 * 100 * 100).take(10).toList
res1: List[Int] = List(1000002, 1000003, 1000004, 1000005, 1000006, 1000007, 1000008, 1000009, 1000010, 1000011)
是的,已经在图书馆了:Iterator.iterate
Iterator.iterate(1)(_ + 1).drop(100 * 100 * 100).take(10).toList
//> List(1000001, 1000002, 1000003, 1000004, 1000005,
1000006, 1000007, 1000008, 1000009, 1000010)
与@Sean Vieira 的基本相同,具有更多类似于 Haskell 的语法:
scala> def iterate[A]: (A => A) => A => Stream[A] = {
| f => x => x #:: iterate(f)(f(x))
| }
iterate: [A]=> (A => A) => (A => Stream[A])
scala> iterate[Int](_+1)(1) take 10 toList
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
交换f
和x
的位置可以帮助编译器:
scala> def iterate[A]: A => (A => A) => Stream[A] = {
| x => f => x #:: iterate(f(x))(f)
| }
iterate: [A]=> A => ((A => A) => Stream[A])
scala> iterate(1)(2+) take 10 toList //Don't need to use iterate[Int] here
res3: List[Int] = List(1, 3, 5, 7, 9, 11, 13, 15, 17, 19)