Iota 0.1.0 Released
We are proud to announce a new open source library, Iota
Iota is a small library to make coproducts easier to use in Scala by providing a simpler syntax with a fast underlying implementation.
Traditional coproduct implementations are implemented as binary trees or linked lists at both the type and value level. The syntax for traditional coproducts can become unwieldy as the number of disjunct types grows.
import cats.data._ // a coproduct of types using scala.util.Either type EitherFoo = Either[Int, Either[String, Double]] // a coproduct of type constructors using cats.data.Coproduct type CoproductBar0[A] = Coproduct[List, Seq, A] type CoproductBar[A] = Coproduct[Option, CoproductBar0, A]
In the example above, both
CoproductBar will become difficult to
read as the number of types increases.
Iota addresses this by using linked lists at the type level.
import iota._ import TList.:: import KList.::: // a coproduct of types type Foo = Cop[Int :: String :: Double :: TNil] // a coproduct of type constructors type Bar[A] = CopK[Option ::: List ::: Seq ::: KNil, A]
At the value level, values are stored directly along with an index of the corresponding type in the type linked list. This allows for minimal overhead when dealing with coproducts of many types.
Additionally, this allows for very fast interpretation of algebras with automatically generated interpreters.
sealed abstract class UserOp[A] sealed abstract class OrderOp[A] sealed abstract class PriceOp[A] type Algebra[A] = CopK[UserOp ::: OrderOp ::: PriceOp ::: KNil, A] val evalUserOp : UserOp ~> Future = dummyInterpreter val evalOrderOp: OrderOp ~> Future = dummyInterpreter val evalPriceOp: PriceOp ~> Future = dummyInterpreter // create the interpreter val evalAlgebra0: Algebra ~> Future = CopK.FunctionK.of( evalUserOp, evalOrderOp, evalPriceOp) // note: order doesn't matter when creating the interpreter since // iota will sort it out for you val evalAlgebra1: Algebra ~> Future = CopK.FunctionK.of( evalOrderOp, evalPriceOp, evalUserOp) // if your interpreters are implicitly available, you can summon // a fan in interpreter implicit val _evalUserOp = evalUserOp implicit val _evalOrderOp = evalOrderOp implicit val _evalPriceOp = evalPriceOp val evalAlgebra2: Algebra ~> Future = CopK.FunctionK.summon
The interpreters created by Iota are optimized for speed and have a
constant evaluation time. The overhead for traditional binary tree
coproducts increases as the number of algebras increase. Below is a
benchmark comparison of the worst case performance of interpreters for
To get started with Iota, checkout the Iota repository on GitHub. Additionally, be sure to check out Freestyle, which relies on Iota for improved runtime performance. Read more on this here: Freestyle 0.1.0 Released.