With the help of scalaz.Unapply
it is possible to write a generic asOption
that works for many different types (those that are supported by Unapply
) and that does not require any additional implicit conversions:
import scalaz._
import Scalaz._
def asOption[MA](ma: MA)(implicit U: Unapply[IsEmpty, MA]): Option[MA] =
if (U.TC.isEmpty(U(ma))) None else Some(ma)
asOption("") //> res0: Option[String] = None
asOption("hello") //> res1: Option[String] = Some(hello)
asOption(List[Int]()) //> res2: Option[List[Int]] = None
asOption(List(1,2)) //> res3: Option[List[Int]] = Some(List(1, 2))
asOption(Map[Int,Int]()) //> res4: Option[Map[Int,Int]] = None
asOption(Map(1 -> 2)) //> res5: Option[Map[Int,Int]] = Some(Map(1 -> 2))
Here is the first part of Unapply
's docstring:
Represents a type
MA
that has been destructured into as a type constructorM[_]
applied to typeA
, along with a corresponding type class instanceTC[M]
.The implicit conversions in the companion object provide a means to obtain type class instances for partially applied type constructors, in lieu of direct compiler support as described in SI-2712.