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( ... )
-
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 otherC
value (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 otherC
value (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
unit: FunctionIO[E, A, Unit]
Maps the output of this effectful function to
Unit
. -
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
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)
).
Deprecated Value Members
-
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