I want to implement class, which describes action about setting some option value. I want to make option 's value type be depent of option type. I am trying to make this:
case class SetOptionMessage[T <: BaseOptionType](
option: T
value: Option[T#ValueType]
)
abstract class BaseOptionType {
type ValueType
}
object SomeBooleanOption extends BaseOptionType {
final type ValueType = Boolean
}
But when I am trying to use that classes like this:
val msg = SetOptionMessage(SomeBooleanOption, Some(true))
I got compilation error:
Error:(15, 43) type mismatch;
found : Some[Boolean]
required: Option[?#ValueType]
SetOptionMessage(SomeBooleanOption, Some(true))
^
How can I proper refer to nested type?
case class SetOptionMessage[V, T <: BaseOptionType{ type ValueType = V }](
option: T,
value: Option[V]
)
val msg = SetOptionMessage(SomeBooleanOption, Some(true))
// msg: SetOptionMessage[Boolean,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,Some(true))
case class SetOptionMessage[V, T <: BaseOptionType](
option: T,
value: Option[V])(implicit e: V =:= T#ValueType)
SetOptionMessage(SomeBooleanOption, Some(true))
// SetOptionMessage[Boolean,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,Some(true))
SetOptionMessage(SomeBooleanOption, None)
// SetOptionMessage[SomeBooleanOption.ValueType,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,None)
You can't use case class
with this solution.
class SetOptionMessage[T <: BaseOptionType](option: T)(val value: Option[T#ValueType])
val msg = new SetOptionMessage(SomeBooleanOption)(Some(true))
// SetOptionMessage[SomeBooleanOption.type] = SetOptionMessage@7f216e0c
msg.value
// Option[SomeBooleanOption.ValueType] = Some(true)
Don't use it.
ValueType
is a path-dependent type. That means you can't access it using #
, which can only refer to non path-dependent types.
Try changing SetOptionMessage
to:
case class SetOptionMessage[T <: BaseOptionType](val option: T,
private val _value: Option[Any]) {
val value = _value.asInstanceOf[Option[option.ValueType]]
}
However, you should not use this solution (check note below). I am keeping the answer undeleted to expose its problems.
NOTE
As @senia indicates in his answer, this is the worst solution since it relies on class cast. This cast presents some limitations as the highlighted in this SO answer: https://stackoverflow.com/a/6690611/1893995
The expression:
val msg = SetOptionMessage(SomeBooleanOption, Some("hello"))
will not only compile but it won't even crash at runtime.
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