implicit class RichSeq[A, C[A] <: Seq[A]](underlying: C[A]{
def cycle: Iterator[A] = {
lazy val circular: Stream[A] = underlying.toStream #::: circular
circular.iterator
}
} implicit class RichSeq[A, C[A] <: Seq[A]](underlying: C[A]{
def cycle: Iterator[A] = {
lazy val circular: Stream[A] = underlying.toStream #::: circular
circular.iterator
}
}All it does is convert a Seq (sequence) to a lazy stream that will infinitely cycle through the values.
Seq(1, 2, 3).cycle.take(8).toList
res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2)
It will work for any seq-like structure (including List. Vector, Queue, etc.)If you try to use it with anything else, like a Map, it won't compile.
Also, note from my example that it's generic and the resulting List is of the correct type.
Just like novice JavaScript developers struggle with "Why 'this' changes here?", it requires some experience with the language.
I don't think so. It is full of syntactic noise, for what is really just notation for building a cyclic structure.
* type annotations stated explicitly, not inferred
* type variables given multiple times
* too much non-verb, non-noun syntax e.g. `#:::`
* and the actual construction of the cycle is stated imperatively with great ceremony (despite it being an applicative)
It is the opposite of dense.
cycle seq = circular where circular = seq ++ circular
(or if you want to really golf it) cycle = fix . (++)
Ok, to be fair the Scala code is a bit more generic as it works for any abstract sequence, but still, Scala's syntax is awfully heavy compared to Haskell.That's one reason I still prefer Haskell even though Scala is easier to sneak into enterprise projects thanks to JVM. Not to mention that Haskell gives stronger static guarantees and has a more sophisticated type inference system.
cycleM = fix . mplus
gives a nice generic version that works on Lists & Sequences but falls afoul of the monomorphism restriction, so it needs a type: cycleM :: (MonadPlus m) => m a -> m a
cycleM = fix . mplusScala, Haskell treat syntax as a chore.
> take 8 $ cycle [1,2,3]
cycleM x = x `mplus` (cycleM x)
take 8 $ cycleM [1,2,3]
might be more generic?