syntax - Custom "let" expression in Scala -
i'd love have let
construct similar 1 in haskell in scala. tried few ways, none seems good. here's code:
object customlet extends app { val data = (i <- 1 1024; j <- 1 512) yield (i % j) * * (i + 1) - 1 def heavycalc() = { println("heavycalc called"); data.sum } def dosomethingwithres(res: int) = { println(s"${res * res}") 1 } def cond(value: int): boolean = value > 256 // not usable, though it's expression (2x heavycalc calls) def withoutlet() = if (cond(heavycalc())) dosomethingwithres(heavycalc()) else 0 // not expression def letwithval(): int = { val res = heavycalc() if (cond(res)) dosomethingwithres(res) else 0 } // lot of code simulate "let", @ least expression def letwithmatch(): int = heavycalc() match { case res => if (cond(res)) dosomethingwithres(res) else 0 } // not perfect solution // http://stackoverflow.com/questions/3241101/with-statement-equivalent-for-scala/3241249#3241249 def let[a, b](param: a)(body: => b): b = body(param) // not bad, i'm not sure if handle more bindings @ once def letwithapp(): int = let(heavycalc()) {res => if (cond(res)) dosomethingwithres(res) else 0} list[(string, () => int)]( ("withoutlet", withoutlet), ("letwithval", letwithval), ("letwithmatch", letwithmatch), ("letwithapp", letwithapp) ).foreach( item => item match { case (title, func) => { println(s"executing $title") val ret = func() println(s"$title finished $ret") println() } } ) }
this ideal of (with 1 binding, more separated ,
; not sure in
keyword):
// desired def lettest(): int = let res = heavycalc() in if (cond(res)) dosomethingwithres(res) else 0
i'm not sure if it's possible, have no experience of advanced scala stuff macros, can't tell.
edit1: clear, main things i'm expecting are: being expression , relatively simple syntax (like 1 outlined above).
you use forward pipe:
object forwardpipecontainer { implicit class forwardpipe[a](val value: a) extends anyval { def |>[b](f: => b): b = f(value) } }
to used this:
import forwardpipecontainer._ def f(i: int) = * println( f(3) |> (x => x * x) )
you can put multiple arguments in tuple:
println( (f(2), f(3)) |> (x => x._1 * x._2) )
which looks better if combined partial function synatx:
println( (f(2), f(3)) |> { case (x, y) => x * y } )
this answer variation of what way of reusing function result in scala, , both based on cache intermediate variable in one-liner got initial idea from.
Comments
Post a Comment