Suppose I am writing:
sealed trait Status
object Error1 extends Status
case class Ok(x: Int) extends Status
def foo(opt: Option[Int]): Status = opt.fold(Error1)(x => Ok(x))
When I try it in REPL I get an error:
scala> def foo(opt: Option[Int]): Status = opt.fold(Error1)(x => Ok(x))
<console>:11: error: type mismatch;
found : Ok
required: Error1.type
def foo(opt: Option[Int]): Status = opt.fold(Error1)(x => Ok(x))
^
I can work it around but it does not look particularly elegant:
// work around the type error above
val error1: Status = Error1
def ok(x: Int): Status = Ok(x)
def foo(opt: Option[Int]): Status = opt.fold(error1)(x => ok(x))
How would you suggest solving this type problem ?
As you see fold
infers return type from the zero/fallback value provided as first arg. There it is Error
as it resolve the most specific type of the value.
You can annotate the fold in the following ways to indicate you want a Status
.
opt.fold[Status](err)(x => Ok(x))
opt.fold(err: Status)(x => Ok(x))
fold signature looks like:
final def fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B
So, it is a curried function with a type parameter B
. So it first executes opt.fold(Error1)
and infers that B is Error1
. So, the second part (x => Ok(x))
should be (f: (A) => Error1)
, and for that reason the compiler complains.
You can fix it being explicit with the type as follows:
scala> def foo(opt: Option[Int]): Status = opt.fold[Status](Error1)(x => Ok(x))
foo: (opt: Option[Int])Status
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With