我不知道如何解决scala中的问题。也许有人可以帮助我!
我有一个带有一些类型参数的case类(Operation
),这个类可以由一个对参数类型一无所知的方法返回(例如来自string
/ {{1}的解析器} / json
)。
所以我需要一种以某种方式从xml
转换为ShadowedOperation
的方法,因为需要从一些数据中解析Operation
并从此提取出类型版本( ShadowedOperation
)。
我编写了一个应该表达问题的代码,它已经简化并尝试做一些不同的事情,但如果能够解决这个问题,我也可以解决真正的需求。
可能Operation
有一个解决方案,但我需要找到一个没有它的解决方案。
shapeless
提前感谢所有可以提供帮助的人!
答案 0 :(得分:1)
我做了一些改变:
为Transform[-A, +B]
增加了协方差/逆差
介绍了类型ShadowedOperation.Aux[I0, O0]
使用fakeParseFromString
修复Aux
的返回类型 - 类型
将案例类的伴随对象中的operationToString
提升为具有相应更改的特征的伴随对象
导入的实例:import op._
整个代码:
object box {
trait Transform[-A, +B] {
def apply(in: A): B
}
object Transform {
def instance[A, B](f: A => B): Transform[A, B] = new Transform[A, B] {
override def apply(in: A): B = f(in)
}
}
implicit class TransformOps[T](w: T) {
def transform(implicit t: Transform[T, String]) = t(w)
}
trait ShadowedOperation {
type I
type O
def param: String
def otherParam: Int
def in: I
def out: O
implicit def operationToString(
implicit
iToString: Transform[I, String],
oToString: Transform[O, String]
): Transform[ShadowedOperation.Aux[I, O], String] =
Transform.instance(in => s"${in.otherParam} - ${in.param} - ${iToString(in.in)} - ${oToString(in.out)}")
}
object ShadowedOperation {
type Aux[I0, O0] = ShadowedOperation { type I = I0; type O = O0 }
}
case class Operation[I0, O0](
param: String,
otherParam: Int,
in: I0,
out: O0
) extends ShadowedOperation {type I = I0; type O = O0}
def fakeParseFromString[I, O](in: Operation[I, O]): ShadowedOperation.Aux[I, O] = in
}
def main(args: Array[String]): Unit = {
import box._
implicit val intToString: Transform[Int, String] = Transform.instance(_.toString)
implicit val stringToString: Transform[String, String] = Transform.instance(_.toString)
val op = Operation("param", 0, "in!", "out!")
val shadowedOperation = fakeParseFromString(op)
import op._
val opString = op.transform
val shadowedOpString = shadowedOperation.transform
println(opString)//0 - param - in! - out!
println(shadowedOpString)//0 - param - in! - out!
}
因此,shapeless
不是必需的。
当你只写ShadowedOperation
而不是ShadowedOperation.Aux[???, ???]
时,你会丢失一些关于类型的信息。您必须找到一种方法来恢复有关I
,O
(某些转换,明确指定类型,定义更多含义等)的信息。否则暗示不会起作用。
例如,在您更新的示例中,您可以编写
def fakeParseFromString(in: String): List[ShadowedOperation.Aux[String, Any]] =
List(Operation("param", 0, "in!","out!"), Operation("param", 0, "in!", 100))
implicit val anyToString: Transform[Any, String] = Transform.instance(_.toString)
val shadowedOpString = shadowedOperationList.map(_.transform)
println(shadowedOpString)
// List(Operation(param,0,in!,out!), Operation(param,0,in!,100))