In the following, I'm trying to make a polymorphic function to convert a RawFeatureValue
into a RefinedFeatureValue
.
import shapeless._
object test {
type RawFeatureValue = Int :+: Double :+: String :+: CNil
type RefinedFeatureValue = Int :+: Double :+: CNil
private object convert extends Poly1 {
implicit def caseInt = at[Int](i => i)
implicit def caseDouble = at[Double](d => d)
implicit def caseString = at[String](s => s.hashCode)
}
val a = Coproduct[RawFeatureValue](12)
val b: RefinedFeatureValue = a map convert
}
However, the resulting type is Int :+: Double :+: Int :+: CNil
which is not compatible with RefinedFeatureValue
.
[error] found : shapeless.:+:[Int,shapeless.:+:[Double,shapeless.:+:[Int,shapeless.CNil]]]
[error] required: test.RefinedFeatureValue
[error] (which expands to) shapeless.:+:[Int,shapeless.:+:[Double,shapeless.CNil]]
[error] val b: RefinedFeatureValue = a map convert
[error] ^
How do I tell shapeless that the two Int
s should be treated as one?
Alternatively, the methods on
Coproduct
s allow to do it without aPoly
(if your real use case allows it) - and less boilerplate. Let's defineThen you can do
This consists in:
RawFeatureValue
into aString
on the one hand, and the remaining elements on the other (which make aRefinedFeatureValue
), withremoveElem
, returning aEither[String, RefinedFeatureValue]
,RefinedFeatureValue
,Either[RefinedFeatureValue, RefinedFeatureValue]
into a singleRefinedFeatureValue
.The most straightforward way to do this I can think of would be to map each element into your target coproduct and then unify the result:
This works as expected:
This solution isn't bad, but it does seem like it might be useful enough to be a single operation.
Alternatively, if you aren't set on a polymorphic function you can use the convert type class in this library: https://github.com/xdotai/typeless/
Here is a convert type class that transforms one Coproduct to an Option of another Coproduct: https://github.com/xdotai/typeless/blob/master/src/main/scala/coproduct/convert.scala
Add to dependencies:
Code: