Created
September 3, 2013 09:31
-
-
Save stanch/6421641 to your computer and use it in GitHub Desktop.
Annotation-based API for scala-workflow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Basic example */ | |
@workflow[List] val x = List(1, 2) * List(4, 5) | |
/* Using @context */ | |
@context[Option] val x = { | |
$(Some(42) + 1) should equal (Some(43)) | |
$(Some(10) + Some(5) * Some(2)) should equal (Some(20)) | |
} | |
@context[List] val x = { | |
$(List(1, 2, 3) * 2) should equal (List(2, 4, 6)) | |
$(List("a", "b") + List("x", "y")) should equal (List("ax", "ay", "bx", "by")) | |
} | |
/* Providing workflow instances */ | |
@context(zipList) val x = { | |
$(List(1, 2, 3, 4) * List(2, 3, 4)) should equal (List(2, 6, 12)) | |
} | |
@context(map[String]) val x = { | |
$(Map("foo" → 10, "bar" → 5) * 2) should equal (Map("foo" → 20, "bar" → 10)) | |
} | |
@context(function[String]) val x = { | |
val chars = (s: String) ⇒ s.length | |
val letters = (s: String) ⇒ s.count(_.isLetter) | |
val nonletters = $(chars - letters) | |
nonletters("R2-D2") should equal (3) | |
} | |
/* Using more complex expressions */ | |
def divide(x: Double, y: Double) = if (y == 0) None else Some(x / y) | |
@workflow[Option] val teen = { | |
val x = divide(1, 2) | |
val y = divide(4, x) | |
divide(y, x) | |
} | |
teen should equal (Some(16)) | |
/* Annotating a method */ | |
@context(function[Env] $ option) | |
def eval: Expr ⇒ Env ⇒ Option[Int] = { | |
case Var(x) ⇒ fetch(x) | |
case Val(value) ⇒ $(value) | |
case Add(x, y) ⇒ $(eval(x) + eval(y)) | |
} | |
/* Shorthand annotations */ | |
@frp val x = { // same as @context(frp) | |
val a = $(10) | |
val b = $(5) | |
val c = $(a + b * 2) | |
(c!) should equal (20) | |
b := 7 | |
(c!) should equal (24) | |
} | |
/* Stack language made easy */ | |
@workflow(stackLang) val program = { put(5); dup; put(7); rot; sub } | |
execute(program) should equal(Right(List(2, 5))) | |
/* Point-free notation */ | |
val isLetter: Char ⇒ Boolean = _.isLetter | |
val isDigit: Char ⇒ Boolean = _.isDigit | |
@workflow(function[Char]) | |
val isLetterOrDigit = isLetter || isDigit | |
val sqr: Double ⇒ Double = x ⇒ x * x | |
val log: Double ⇒ Double = x ⇒ math.log(x) | |
@context(function[Double]) | |
val g = log andThen $((sqr - 1) / (sqr + 1)) // (sqr(log(x)) - 1) / (sqr(log(x)) + 1) | |
/* Purely functional logging */ | |
@context(writer[Log]) | |
val Writer(result, logEntries) = ${ | |
log("Lets define a variable") | |
val x = 2 | |
log("And calculate a square of it") | |
val square = x * x | |
log("Also a cube and add them together") | |
val cube = x * x * x | |
val sum = square + cube | |
log("This is all so silly") | |
30 / 5 | |
} | |
result should equal (6) | |
logEntries should equal (Log(List("Lets define a variable", | |
"And calculate a square of it", | |
"Also a cube and add them together", | |
"This is all so silly"))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment