Skutek has evolved to, and been superseded by Turbolift. Turbolift retains most of features and syntax of Skutek. But it internally, it's no longer based on Eff monad.
Skutek (pronounced: skoo-tech) is a framework implementing a monad of extensible effects (a.k.a. One monad to rule them all), based on Freer monad, adapted to leverage specifics of Scala's type system, with main differences being:
-
Use of intersection types in lieu of union types (which Scala doesn't have), to model sets of effects.
-
Use of classic OOP inheritence as the way of extending the monad with new operations.
import skutek.abstraction._
import skutek.std_effects._
object Main extends App {
// Declare some effects:
case object MyReader extends Reader[Int]
case object MyState extends State[Int]
case object MyExcept extends Except[String]
// Create a monadic computation using those effects:
val computation = for {
a <- MyState.Get
b <- MyReader.Ask
c <- {
if (b != 0)
Return(a / b)
else
MyExcept.Raise(s"Tried to divide $a by zero")
}
_ <- MyState.Put(c)
} yield ()
// Create a handler for the above computation, by composing
// individual handlers of each requested effect:
val handler = MyExcept.handler <<<! MyState.handler(100).exec <<<! MyReader.handler(3)
// Execute the computation using the handler:
val result = handler.run(computation)
println(result) // prints "Right(33)"
}
The inferred type of computation
above is equivalent to:
Unit !! MyState.type with MyReader.type with MyExcept.type
where !!
is infix type alias for Computation monad:
Computation[Unit, MyState.type with MyReader.type with MyExcept.type]
More usage in examples directory.
libraryDependencies += "com.github.marcinzh" %% "skutek-core" % "0.16.0"
Cross built Built for Scala 2.13.
Warning: contains links to partially outdated and somewhat embarrassing manual.
-
Simplicity of use:
- No need of defining the effect stack upfront.
- No need of lifting of operations into the monad.
- Effect subtyping.
-
Simplicity of implementation:
- No dependencies on external libraries.
- No clever type-fu, no macros. Mostly immutable OOP style.
-
Practical stuff:
- Predefined set of basic effects (
Reader
,Writer
, etc.). Read more. - Conflict proof: ability for multiple instances of the same type of effect, to coexist in the same effect stack (e.g.
State[Int]
andState[String]
). - Potentially parallel execution of effects. Read more.
- Support for
for
comprehension guards, for effects compatible with filtering (e.g.Maybe
,Choice
). - Tested stack safety.
- Predefined set of basic effects (
-
Caveats and limitations:
- General infancy of the project.
NoLimited possiblity of adapting pre-existing monads as Skutek's effects.- Removing effects from the stack (local handling) isn't as easy as adding them. Read more.
- Rare occurences of false positives by Scala's linter (i.e. "inferred
Any
"). Read more. - Using patterns in
for
comprehensions can trigger surprising compiler errors. It can be mitigated by This compiler plugin. - Lack of performance analysis.
Concurrency
effect is a hack.
WIP. Partially outdated since many breaking chanches in 0.10.0