gpt4 book ai didi

scala - 将 scala List[String]/List[Object] 转换为 model/HList/tuple

转载 作者:行者123 更新时间:2023-12-01 13:47:19 24 4
gpt4 key购买 nike

外部系统返回 Seq[String](一种 DB,类似 CSV/json 的输出),它是基本类型的包装:字符串/数字。我宁愿使用我自己的模型。

object Converter {
type Output = (Int, String, Double) // for instance
def convert(values: List[String]): Output
}

显然,我不想每次都执行 convert-method。

看来我需要的东西比 http://nrinaudo.github.io/tabulate/tut/parsing.html

这里可以用HList吗?就像通过定义显式的仅输出类型将大小的 HList (String::String::String::HNil) 转换为模型。

最佳答案

首先,convert 方法的输出必须是 Option[Output],或者 Output 的一些单子(monad)(TryEitherscalaz.\/scalaz.Validation 等)以防 的内容>Seq[String] 无法转换为Output(Seq 长度错误,Int 解析错误或 double 等)

shapeless 的可能实现将有一个类型类将 String 转换为其参数类型,以及一个辅助类型类将 HList 转换为String 到具有第一个类型类的 OutputHList 表示。

这是一个示例实现:

import shapeless._
import shapeless.syntax.std.traversable._
import shapeless.ops.traversable._

trait Parse[Out] {
def apply(value: String): Option[Out]
}
object Parse {
implicit object convertToInt extends Parse[Int] {
def apply(value: String) = Try(value.toInt).toOption
}

implicit object convertToString extends Parse[String] {
def apply(value: String) = Some(value)
}

implicit object convertToDouble extends Parse[Double] {
def apply(value: String) = Try(value.toDouble).toOption
}
}

trait ParseAll[Out] {
type In <: HList
def apply(values: In): Option[Out]
}

object ParseAll {

type Aux[I, O] = ParseAll[O] { type In = I }

implicit object convertHNil extends ParseAll[HNil] {
type In = HNil
def apply(value: HNil) = Some(HNil)
}

implicit def convertHList[T, HO <: HList](implicit
cv: Parse[T],
cl: ParseAll[HO]
) = new ParseAll[T :: HO] {
type In = String :: cl.In
def apply(value: In) = value match {
case x :: xs => for {
t <- cv(x)
h0 <- cl(xs)
} yield t :: h0
}
}
}

trait Converter {
type Output
def convert[S <: HList, H <: HList](values: List[String])(implicit
gen: Generic.Aux[Output, H], // Compute HList representation `H` of Output
parse: ParseAll.Aux[S, H], // Generate parser of Hlist of String `S` to HList `H`
ft: FromTraversable[S] // Generate converter of `List[String]` to HList of Strings `S`
): Option[Output] =
values.toHList[S].flatMap(parse.apply).map(gen.from)
}

升级此实现以返回您选择的错误 monad(或抛出异常)而不是返回 Option

很简单

下面是你如何使用它:

scala> object ConverterISD extends Converter {
type Output = (Int, String, Double)
}

defined object ConverterISD

scala> ConverterISD.convert(List("1", "foo", "2.34"))
res0: Option[ConverterISD.Output] = Some((1,foo,2.34))

scala> ConverterISD.convert(List("1", "foo", "2.34", "5"))
res1: Option[ConverterISD.Output] = None

scala> ConverterISD.convert(List("1", "foo", "bar"))
res2: Option[ConverterISD.Output] = None

它也适用于案例类而不是元组:

scala> case class Model(i: Int, d: Double)

defined class Model

scala> object ConverterModel extends Converter {
type Output = Model
}

defined object ConverterModel

scala> ConverterModel.convert(List("1", "2.34"))
res0: Option[ConverterModel.Output] = Some(Model(1,2.34))

scala> ConverterModel.convert(List("1"))
res1: Option[ConverterModel.Output] = None

scala> ConverterModel.convert(List("1", "foo"))
res2: Option[ConverterModel.Output] = None

关于scala - 将 scala List[String]/List[Object] 转换为 model/HList/tuple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34982555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com