我想写>hdfs dfs -ls
>ls: Call From hadoop-n2/XXX.XXX.XX.XX to hadoop-n2:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
。 def parse[T <: HList](list: List[String]): Validation[T]
可以是list
,List("fooid", "barid")
T
,以及实现FooId :: BarId :: HNil
的类型Parse[T]
。我如何写String => Validation[FooId]
,将列表解析为parse
?我不确定如何为T
的每个元素召唤隐式类型类。
答案 0 :(得分:2)
我们可以调整shapeless.ops.traversable.FromTraversable
的代码。
我不确定您的Validation
类型是什么,但我将其用作下面scalaz.ValidationNel[String, A]
的别名(主要是因为我可以使用string
语法轻松地给出我有些Parse
个实例)。
import scalaz.{Validation => _, _}, Scalaz._
type Validation[A] = ValidationNel[String, A]
trait Parse[T] {
def apply(s: String): Validation[T]
}
object Parse {
def fromScalazParse[E <: Exception, T](f: String => scalaz.Validation[E, T]) =
new Parse[T] {
def apply(s: String): Validation[T] =
f(s).leftMap(_.getMessage).toValidationNel
}
implicit val booleanParse = fromScalazParse(_.parseBoolean)
implicit val intParse = fromScalazParse(_.parseInt)
implicit val doubleParse = fromScalazParse(_.parseDouble)
}
对Parser
类型类进行排序后,我们现在可以基于FromTraversable
创建一个类型类来解析List[String]
并给我们一个Validation[A :: B :: HNil]
:
import shapeless._
import scala.collection.GenTraversable
trait FromTraversableParsed[Out <: HList] extends Serializable {
def apply(l: GenTraversable[String]) : Validation[Out]
}
object FromTraversableParsed {
def apply[Out <: HList](implicit from: FromTraversableParsed[Out]) = from
implicit val hnilFromTraversableParsed =
new FromTraversableParsed[HNil] {
def apply(l: GenTraversable[String]): Validation[HNil] =
if(l.isEmpty) HNil.successNel[String]
else "Traversable is not empty".failureNel[HNil]
}
implicit def hlistFromTraversableParsed[OutH, OutT <: HList](implicit
ftpT: FromTraversableParsed[OutT],
parseH: Parse[OutH]
): FromTraversableParsed[OutH :: OutT] =
new FromTraversableParsed[OutH :: OutT] {
def apply(l : GenTraversable[String]) : Validation[OutH :: OutT] =
if(l.isEmpty) "Empty traversable".failureNel[OutH :: OutT]
else (parseH(l.head) |@| ftpT(l.tail))(_ :: _)
}
}
我们可以添加一些语法,以便更轻松地使用FromTraversableParsed
:
implicit class ParseStringListOps(val strings: List[String]) extends AnyVal {
def parse[L <: HList](implicit ftp: FromTraversableParsed[L]): Validation[L] =
ftp(strings)
}
现在我们可以做到:
List("1", "true", "3.0").parse[Int :: Boolean :: Double :: HNil]
// Validation[Int :: Boolean :: Double :: HNil] = Success(1 :: true :: 3.0 :: HNil)