Last active
December 5, 2018 23:38
-
-
Save frgomes/21670dfdb294809452bdc5b790cdef06 to your computer and use it in GitHub Desktop.
scala - convenience implicit conversions for optional types
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
package rgomes.info.lang | |
import utest._ | |
object OptionalSyntaxSpec extends TestSuite { | |
trait OptionalWrapper[T] { | |
def wrap(data: T): Option[T] | |
} | |
object OptionalInstances { | |
import scala.language.implicitConversions | |
import scala.language.higherKinds | |
implicit object StringConverter extends OptionalWrapper[String] { implicit def wrap(a: String) : Option[String] = Option(a) } | |
implicit object IntConverter extends OptionalWrapper[Int] { implicit def wrap(a: Int) : Option[Int] = Option(a) } | |
implicit object LongConverter extends OptionalWrapper[Long] { implicit def wrap(a: Long) : Option[Long] = Option(a) } | |
implicit object FloatConverter extends OptionalWrapper[Float] { implicit def wrap(a: Float) : Option[Float] = Option(a) } | |
implicit object DoubleConverter extends OptionalWrapper[Double] { implicit def wrap(a: Double) : Option[Double] = Option(a) } | |
implicit object BooleanConverter extends OptionalWrapper[Boolean] { implicit def wrap(a: Boolean): Option[Boolean] = Option(a) } | |
/* This one is more elaborated: OptionWrapper[Seq[A]] needs OptionWrapper[A], which can be found implicitly. */ | |
implicit def SeqWrapper[A](implicit itemWrapper: OptionalWrapper[A]): OptionalWrapper[Seq[A]] = new OptionalWrapper[Seq[A]] { | |
def wrap(a: Seq[A]): Option[Seq[A]] = Option(a) | |
} | |
/* This one is more elaborated: OptionWrapper[List[A]] needs OptionWrapper[A], which can be found implicitly. */ | |
implicit def ListWrapper[A](implicit itemWrapper: OptionalWrapper[A]): OptionalWrapper[List[A]] = new OptionalWrapper[List[A]] { | |
def wrap(a: List[A]): Option[List[A]] = Option(a) | |
} | |
} | |
trait OptionalSyntax { | |
import scala.language.implicitConversions | |
implicit def wrap[A](a: A)(implicit o: OptionalWrapper[A]): Option[A] = o.wrap(a) | |
} | |
val tests = this { | |
"Ability to wrap a String" - { | |
object CallSite extends OptionalSyntax { | |
import OptionalInstances._ | |
val s: Option[String] = "this is a String" | |
} | |
assert(CallSite.s == Some("this is a String")) | |
} | |
... | |
"Ability to wrap List[A]" - { | |
object CallSite extends OptionalSyntax { | |
import OptionalInstances._ | |
val xs: Option[List[String]] = List("a", "b", "c") | |
val xi: Option[List[Int]] = List(1, 2, 3) | |
val xl: Option[List[Long]] = List(1L, 2L, 3L) | |
val xf: Option[List[Float]] = List(1.0f, 2.0f, 3.0f) | |
val xd: Option[List[Double]] = List(1.0, 2.0, 3.0) | |
val xb: Option[List[Boolean]] = List(true, false, true) | |
} | |
assert(CallSite.xs == Some(List("a", "b", "c"))) | |
assert(CallSite.xi == Some(List(1, 2, 3))) | |
assert(CallSite.xl == Some(List(1L, 2L, 3L))) | |
assert(CallSite.xf == Some(List(1.0f, 2.0f, 3.0f))) | |
assert(CallSite.xd == Some(List(1.0, 2.0, 3.0))) | |
assert(CallSite.xb == Some(List(true, false, true))) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is an example of how a typeclass can be implemented.