I have a question very similar to this one: Scala higher kinded type variance
This, however is slightly different in that, well, it doesn't compile (scala 2.11.8).
The basic idea is to take a provided array of "things". If the array is null, return a default value of some type (e.g. Boolean
, Option
, List[Int]
), otherwise do work on the array and produce a result. The result and default value have the same type.
The challenge I'm having is getting this to work across a broad set of result types.
Here's a contrived example:
trait NullGuard[F[_]] {
def nullGuard[A, B](arr: Array[A], default: F[B])(expr: => F[B]): F[B] =
if (arr == null || arr.length == 0) default else expr
}
Let's create an implementation that returns an Option:
implicit def optionNullGuard[F[X] <: Option[X]]: NullGuard[F] = new NullGuard[F]() {}
The above does compile, but the following attempt to use the above type class does not:
def returnsOption[F[_], A, B](arr: Array[A])(implicit ng: NullGuard[F]): Option[B] = {
ng.nullGuard(arr, None) {
// sample work
if (arr.length % 2 == 0) Option(1) else None
}
}
I get the following compile error:
type mismatch;
found : None.type
required: F[?]
ng.nullGuard(arr, None){
How can I get this to work? I'm also open to another approach, if there is one.
C[X] <: Option[X]
good for? Do you expect to have any strict subclasses ofOption
in your code? (there should be onlyNone
andSome
anyway, because the trait is sealed). – Andrey TyukinSome
orNone
. I'm pretty new at this so I'm not sure what is required, and what isn't, to make this work – ErikA <: Array[A]
also looks somewhat mysterious. Could you maybe elaborate what exactly you wanted to achieve with that? – Andrey Tyukindef nullGuard[A, B](arr: Array[A], default: Res[B])...
. (I updated my sample code above to reflect this) – Erik