我正在尝试为Gen[Stream[A]]
s的无限(懒惰评估)流定义A
,其中每个元素A
可以依赖于之前的元素。
作为最小的情况,我们可以使用Gen[Stream[Int]]
,其中下一个元素是前一个元素的+1
或+2
。这里有一个haskell实现参考:
increasingInts :: Gen [Int]
increasingInts = arbitrary >>= go
where
go seed = do
inc <- choose (1,2)
let next = seed + inc
rest <- go next
return (next : rest)
我在Gen.sequence
上尝试了Stream[Gen[A]]
,但得到了一个stackoverflow。我还尝试从头开始定义Gen
,但gen
的构造函数Gen
是私有的,可以使用私有方法/类型。
此尝试还提供了stackoverflow。
def go(seed: Int): Gen[Stream[Int]] =
for {
inc <- Gen.choose(1, 2)
next = seed + inc
rest <- Gen.lzy(go(next))
} yield next #:: rest
val increasingInts: Gen[Stream[Int]] = go(0)
increasingInts(Gen.Parameters.default, Seed.random()).get foreach println
所以我被困住了。有什么想法吗?
答案 0 :(得分:0)
您可以通过以下方式实现您的目标:
val increasingInts = {
val increments = Gen.choose(1, 2)
val initialSeed = 0
for {
stream <- Gen.infiniteStream(increments)
} yield stream.scanLeft(initialSeed)(_ + _)
}
.scanLeft
与.foldLeft
类似,但会保留中间值,从而为您提供另一个Stream
。
我在这里写过scanLeft
:https://www.scalawilliam.com/most-important-streaming-abstraction/