sealed abstract classAndThen[-T, +R] extends (T) ⇒ R with Product with Serializable
A function type of a single input that can do function composition
(via andThen and compose) in constant stack space with amortized
linear time application (in the number of constituent functions).
Example:
val seed = AndThen((x: Int) => x + 1))
val f = (0 until 10000).foldLeft(seed)((acc, _) => acc.andThen(_ + 1))
// This should not trigger stack overflow ;-)
f(0)
This can be used to build stack safe data structures that make
use of lambdas. The perfect candidates for usage with AndThen
are the data structures using a signature like this (where
F[_] is a monadic type):
A => F[B]
As an example, if we described this data structure, the naive
solution for that map is stack unsafe:
caseclass Resource[F[_], A, B](
acquire: F[A],
use: A => F[B],
release: A => F[Unit]) {
def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = {
Resource(
ra.acquire,
// Stack Unsafe!
a => ra.use(a).map(f),
ra.release)
}
}
To describe a flatMap operation for this data type, AndThen
can save the day:
def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = {
Resource(
ra.acquire,
AndThen(ra.use).andThen(_.map(f)),
ra.release)
}
A function type of a single input that can do function composition (via
andThen
andcompose
) in constant stack space with amortized linear time application (in the number of constituent functions).Example:
This can be used to build stack safe data structures that make use of lambdas. The perfect candidates for usage with
AndThen
are the data structures using a signature like this (whereF[_]
is a monadic type):A => F[B]
As an example, if we described this data structure, the naive solution for that
map
is stack unsafe:To describe a
flatMap
operation for this data type,AndThen
can save the day: