Last active
December 17, 2015 12:29
-
-
Save JasonGiedymin/5609984 to your computer and use it in GitHub Desktop.
Quick experiment with option list of values, option list of functions, and lifting both for binding/executing.
This file contains 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
package jason | |
import org.scalatest.FreeSpec | |
class OptionLiftSpec extends FreeSpec { | |
def fTimesTwo(x: Int): Option[Int] = Some(x * 2) | |
def fTimesThree(x: Int): Option[Int] = Some(x * 3) | |
def fHalf(x: Int): Option[Int] = Some(x / 2) | |
def fDivideThree(x: Int): Option[Int] = Some(x / 3) | |
/** | |
* iterate over map | |
*/ | |
"Composition test" - { | |
type IntFunc = (Int) => Option[Int] | |
type OptIntFunc = Option[IntFunc] | |
val myIntList: List[Option[Int]] = List[Option[Int]](Some(1), None, Some(2), Some(3)) | |
val myFuncs: List[IntFunc] = List[IntFunc](fTimesTwo, fTimesThree, fHalf, fDivideThree) | |
val optMyFuncs: List[OptIntFunc] = List[OptIntFunc](Some(fTimesTwo _), Some(fTimesThree _), Some(fHalf _), Some(fDivideThree _), None) | |
"For comprehension lifting with Options" - { | |
"With manual composition" in { | |
//val x = myList flatMap(fTimesTwo) | |
val x = for { | |
i <- myIntList | |
iR <- i | |
y <- fTimesTwo(iR) | |
y2 <- fTimesThree(y) | |
y3 <- fHalf(y2) | |
y4 <- fDivideThree(y3) | |
} yield y4 | |
info("Manual composition: %s" format x.toString()) | |
assert(x === List(1, 2, 3)) | |
} | |
} | |
"Manual Option composition and mapping" in { | |
/* Without Option Function List, but raw type | |
// ver 1 | |
val x = myIntList.flatMap{ num:Option[Int] => | |
optMyFuncs.foldLeft(num){ (curr:Option[Int], fx:OptIntFunc) => | |
fx match { | |
case Some(o) => curr flatMap o | |
case _ => None | |
} | |
} | |
} | |
// ver 2 | |
val x = myList.flatMap{ num:Option[Int] => | |
myFuncs.foldLeft(num){ (curr:Option[Int], fx:IntFunc) => | |
curr flatMap fx | |
} | |
} | |
// ver 3 | |
//Mind blown... (below is == to above) | |
val x = myList.flatMap(myFuncs.foldLeft(_)(_ flatMap _)) | |
*/ | |
val x = myIntList.flatMap(optMyFuncs.flatten.foldLeft(_)(_ flatMap _)) | |
info("Manual result: %s" format x) | |
assert(x === List(1, 2, 3)) | |
} | |
"Comprehensions with defined fold" in { | |
// Takes a bit from the above but will allow for | |
// projection + futures | |
def calc(num: Option[Int]) = myFuncs.foldLeft(num) { | |
(curr: Option[Int], fx: IntFunc) => | |
curr flatMap fx | |
} | |
def calc2(num: Option[Int]) = myFuncs.foldLeft(num)(_ flatMap _) | |
val x = for { | |
i <- myIntList | |
r <- optMyFuncs.flatten.foldLeft(i)(_ flatMap _) | |
} yield r | |
info("Comprehension lifting result: %s" format x.toString) | |
assert(x === List(1, 2, 3)) | |
} | |
//TODO: add futures here | |
"Optimized Comprehensions with defined fold" in { | |
// Takes a bit from the above but will allow for | |
// projection + futures | |
def calc(num: Option[Int]) = myFuncs.foldLeft(num) { | |
(curr: Option[Int], fx: IntFunc) => | |
curr flatMap fx | |
} | |
def calc2(num: Option[Int]) = myFuncs.foldLeft(num)(_ flatMap _) | |
val x = for { | |
i <- myIntList | |
r <- optMyFuncs.flatten.foldLeft(i)(_ flatMap _) | |
} yield r | |
info("Comprehension lifting result: %s" format x.toString) | |
assert(x === List(1, 2, 3)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment