sealed trait FunctionIO[+E, -A, +B] extends Serializable
A FunctionIO[E, A, B] is an effectful function from A to B, which might
fail with an E.
This is the moral equivalent of A => IO[E, B], and, indeed, FunctionIO
extends this function type, and can be used in the same way.
The main advantage to using FunctionIO is that it provides you a means of
importing an impure function A => B into FunctionIO[E, A, B], without
actually wrapping the result of the function in an IO value.
This allows the implementation to aggressively fuse operations on impure
functions, which in turn can result in significantly higher-performance and
far less heap utilization than equivalent approaches modeled with IO.
The implementation allows you to lift functions from A => IO[E, B] into a
FunctionIO[E, A, B]. Such functions cannot be optimized, but will be handled
correctly and can work in conjunction with optimized (fused) FunctionIO.
Those interested in learning more about modeling effects with FunctionIO are
encouraged to read John Hughes paper on the subject: Generalizing Monads to
Arrows (www.cse.chalmers.se/~rjmh/Papers/arrows.pdf). The implementation in
this file contains many of the same combinators as Hughes implementation.
A word of warning: while even very complex code can be expressed in
FunctionIO, there is a point of diminishing return. If you find yourself
using deeply nested tuples to propagate information forward, it may be no
faster than using IO.
Given the following two FunctionIO:
val readLine = FunctionIO.impureVoid((_ : Unit) => scala.Console.readLine()) val printLine = FunctionIO.impureVoid((line: String) => println(line))
Then the following two programs are equivalent:
// Program 1 val program1: UIO[Unit] = for { name <- getStrLn _ <- putStrLn("Hello, " + name) } yield ()) // Program 2 val program2: UIO[Unit] = (readLine >>> FunctionIO.fromFunction("Hello, " + _) >>> printLine)(())
Similarly, the following two programs are equivalent:
// Program 1 val program1: UIO[Unit] = for { line1 <- getStrLn line2 <- getStrLn _ <- putStrLn("You wrote: " + line1 + ", " + line2) } yield ()) // Program 2 val program2: UIO[Unit] = (readLine.zipWith(readLine)("You wrote: " + _ + ", " + _) >>> printLine)(())
In both of these examples, the FunctionIO program is faster because it is
able to perform fusion of effectful functions.
- Self Type
- FunctionIO[E, A, B]
- Alphabetic
- By Inheritance
- FunctionIO
- Serializable
- Serializable
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Abstract Value Members
Concrete Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##(): Int
- Definition Classes
- AnyRef → Any
- final def &&&[E1 >: E, A1 <: A, C](that: FunctionIO[E1, A1, C]): FunctionIO[E1, A1, (B, C)]
Returns a new effectful function that zips together the output of two effectful functions that share the same input.
- final def <<<[E1 >: E, C](that: FunctionIO[E1, C, A]): FunctionIO[E1, C, B]
A symbolic operator for
compose. - final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def >>>[E1 >: E, C](that: FunctionIO[E1, B, C]): FunctionIO[E1, A, C]
A symbolic operator for
andThen. - final def andThen[E1 >: E, C](that: FunctionIO[E1, B, C]): FunctionIO[E1, A, C]
"Backwards" composition of effectful functions.
- final def asEffect[A1 <: A]: FunctionIO[E, A1, A1]
Returns a new effectful function that merely applies this one for its effect, returning the input unmodified.
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @native() @throws(classOf[java.lang.CloneNotSupportedException])
- final def compose[E1 >: E, A0](that: FunctionIO[E1, A0, A]): FunctionIO[E1, A0, B]
Composes two effectful functions.
- final def const[C](c: ⇒ C): FunctionIO[E, A, C]
Maps the output of this effectful function to the specified constant.
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- final def first[A1 <: A, B1 >: B]: FunctionIO[E, A1, (B1, A1)]
Returns a new effectful function that computes the value of this function, storing it into the first element of a tuple, carrying along the input on the second element of a tuple.
- final def flatMap[E1 >: E, A1 <: A, C](f: (B) ⇒ FunctionIO[E1, A1, C]): FunctionIO[E1, A1, C]
Binds on the output of this effectful function.
- final def getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def left[C]: FunctionIO[E, Either[A, C], Either[B, C]]
Returns a new effectful function that can either compute the value of this effectful function (if passed
Left(a)), or can carry along any otherCvalue (if passedRight(c)). - final def map[C](f: (B) ⇒ C): FunctionIO[E, A, C]
Maps the output of this effectful function by the specified function.
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def right[C]: FunctionIO[E, Either[C, A], Either[C, B]]
Returns a new effectful function that can either compute the value of this effectful function (if passed
Right(a)), or can carry along any otherCvalue (if passedLeft(c)). - final def second[A1 <: A, B1 >: B]: FunctionIO[E, A1, (A1, B1)]
Returns a new effectful function that computes the value of this function, storing it into the second element of a tuple, carrying along the input on the first element of a tuple.
- final def synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def void: FunctionIO[E, A, Unit]
Maps the output of this effectful function to
Unit. - final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws(classOf[java.lang.InterruptedException])
- final def zipWith[E1 >: E, A1 <: A, C, D](that: FunctionIO[E1, A1, C])(f: (B, C) ⇒ D): FunctionIO[E1, A1, D]
Zips the output of this function with the output of that function, using the specified combiner function.
- final def |||[E1 >: E, B1 >: B, C](that: FunctionIO[E1, C, B1]): FunctionIO[E1, Either[A, C], B1]
Returns a new effectful function that will either compute the value of this effectful function (if passed
Left(a)), or will compute the value of the specified effectful function (if passedRight(c)).