For building DSLs (Domain-Specific Languages) that allow the composition of pure and fully type-safe expressions such that any sub-expression may generate or receive errors as input, short-circuiting evaluation. Such DSLs include support for readers that can read for weakly-typed (i.e. "unsafe") data sources.
resolvers ++= Seq(
"jitpack" at "https://jitpack.io"
)
libraryDependencies ++= Seq(
"com.github.ryanonsrc" % "espresso" % "v1.1.4"
)
espresso makes extensive use of the Typelevel cats and shapeless libraries as well as the kind-projector compiler plugin.
Take a look at https://github.com/ryanonsrc/espresso/tree/master/src/test/scala/io/nary/espresso/sample
Term[E, A]- represents a term within an expression, evaluating to an error of typeEor result of typeAExpr[E, A, B]- for any expression taking a value of typeAand evaluating to either a result of typeBor an error of typeEIn[E, A]- weakly-typedAnyinput from "the outside world" that can be "read" into an expression as either value of typeAor an error of typeEopN[E, A1, ... AN, B]- wraps an operation:(Term[E, A1],...,Term[E, AN]) => (Term[E, B])produces anExpr[E, (A1,...,AN), B]joinN[E, A, B1, ... BN]- combine an tuple ofNexpressions:Expr[E, A, Bi]into a singleExpr[E, A, (B1,...,BN)]evalN[E, A, B1, ... BN, C]- GivenNexpressions:Expr[E, A, Bi]and operation:Expr[E, (B1,...,BN), C], generateExpr[E, A, C]
const[E, A, B]- lift a value of typeBdirectly into an expression (bypassing the need to read from a weakly-typed sourceA)error[E, A, B]- lift an error instance of typeEdirectly into an expression (bypassing the need to read from a weakly-typed sourceA)funcExprN[E, A1,... AN, B]- lift functions of type(A1, ..., AN) => BString => E(for errors) into the expression:Expr[E, (A1,...,AN), B]
create any implicit readers/conversions needed for "reading" values from Source using the espresso.adapters.reader:
-
def read[E, A, K, S](k: K, orElse: E, f: S => K => In[E, A] => Option[Term[E, A]]) (using i: In[E, A]): Expr[E, S, A] - define your library of
Expr[E, A, B]operations either usingopN-wrappers or lifted-funcExprNs - create your DSL syntax in the form of an
extensionof l-Expr[<Your DSL Error type>, <Your DSL expression data source type>, <Your DSL produced value type>]as functions that will evaluate the l-Exprwith a provided library function using anevalNcombinator
