Wednesday, 15 February 2012

scala currying/partials to build function filter list -



scala currying/partials to build function filter list -

given next code:

case class config( addthree: boolean = true, halve: boolean = true, timesfive: boolean = true ) def doops(num: integer, config: config): integer = { var result: integer = num if ( config.addthree ) { result += 3 } if ( config.halve ) { result /= 2 } if ( config.timesfive ) { result *= 5 } result } val config = config(true,false,true) println( doops(20, config) ) println( doops(10, config) )

i'd replace ugly doops method more efficient , idiomatic construct. specifically, i'd build chain of functions performs required transformations based on specific config beingness used. know want create sort of partially applied function can pass integer into, i'm drawing blank @ how accomplish in efficient way.

i want avoid if statements within doops, want resulting construction chain of functions calls next 1 in chain without checking conditional first.

the resulting code, imagine this:

case class config( addthree: boolean = true, halve: boolean = true, timesfive: boolean = true ) def builddoops(config: config) = ??? val config = config(true,false,true) def doops1 = builddoops(config) println( doops1(20) ) println( doops1(10) )

here suggestion. create sequence of functions independent each other. if 1 of operations disabled, replace identity. in end foldleft on sequence, using num argument initial value:

case class config( addthree: boolean = true, halve: boolean = true, timesfive: boolean = true ) { private val funchain = seq[int => int]( if(addthree) _ + 3 else identity _, if(halve) _ / 2 else identity _, if(timesfive) _ * 5 else identity _ ) def doops(num: int) = funchain.foldleft(num){(acc, f) => f(acc)} }

i placed doops() within config fits there nicely.

config(true, false, true).doops(10) //(10 + 3 ) * 5 = 65

if masochist, foldleft() can written this:

def doops(num: int) = (num /: funchain){(acc, f) => f(acc)}

if don't identity, utilize option[int => int] , flatten:

private val funchain = seq[option[int => int]]( if(addthree) some(_ + 3) else none, if(halve) some(_ / 2) else none, if(timesfive) some(_ * 5) else none ).flatten

scala partials currying

No comments:

Post a Comment