Packages

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]
Linear Supertypes
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. FunctionIO
  2. Serializable
  3. Serializable
  4. AnyRef
  5. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Abstract Value Members

  1. abstract val run: (A) ⇒ IO[E, B]

    Applies the effectful function with the specified value, returning the output in IO.

Concrete Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. 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.

  4. final def <<<[E1 >: E, C](that: FunctionIO[E1, C, A]): FunctionIO[E1, C, B]

    A symbolic operator for compose.

  5. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  6. final def >>>[E1 >: E, C](that: FunctionIO[E1, B, C]): FunctionIO[E1, A, C]

    A symbolic operator for andThen.

  7. final def andThen[E1 >: E, C](that: FunctionIO[E1, B, C]): FunctionIO[E1, A, C]

    "Backwards" composition of effectful functions.

  8. 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.

  9. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  10. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  11. final def compose[E1 >: E, A0](that: FunctionIO[E1, A0, A]): FunctionIO[E1, A0, B]

    Composes two effectful functions.

  12. final def const[C](c: ⇒ C): FunctionIO[E, A, C]

    Maps the output of this effectful function to the specified constant.

  13. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  14. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  15. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  16. 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.

  17. 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.

  18. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  19. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  20. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  21. 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 other C value (if passed Right(c)).

  22. final def map[C](f: (B) ⇒ C): FunctionIO[E, A, C]

    Maps the output of this effectful function by the specified function.

  23. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  24. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  25. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  26. 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 other C value (if passed Left(c)).

  27. 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.

  28. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  29. def toString(): String
    Definition Classes
    AnyRef → Any
  30. final def unit: FunctionIO[E, A, Unit]

    Maps the output of this effectful function to Unit.

  31. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  32. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  33. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  34. 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.

  35. 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 passed Right(c)).

Deprecated Value Members

  1. final def void: FunctionIO[E, A, Unit]

    Maps the output of this effectful function to Unit.

    Maps the output of this effectful function to Unit.

    Annotations
    @deprecated
    Deprecated

    (Since version 1.0.0) use unit

Inherited from Serializable

Inherited from Serializable

Inherited from AnyRef

Inherited from Any

Ungrouped