我想寫def parse[T <: HList](list: List[String]): Validation[T]
。 list
可以是List("fooid", "barid")
和T
FooId :: BarId :: HNil
,以及實現String => Validation[FooId]
的類型類別Parse[T]
。我怎麼會寫parse
,解析列表爲T
?我不知道如何爲T
的每個元素召喚隱式類型類。Parse List [String] into HList
1
A
回答
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)
相關問題
- 1. populate Dictionary <string,List <string>> into android
- 2. python list into dict
- 3. 將Scala中的List [String,String]變爲List [String,List [String]]?
- 4. 如何將List [List [Map [String,String]]]轉換爲List [Map [String,String]]
- 5. Arraylist value into string
- 6. Parse String to double []
- 7. Swift String into
- 8. CodeName One List/Multi-List text into multiple rows
- 9. int32.Parse(String,IFormatProvider)通過int32.Parse(String)的用例是什麼?
- 10. python string list to list ast.listeral_eval
- 11. add「into String變量
- 12. Split StudlyCaps string into words
- 13. Haskell string to list
- 14. python string to list
- 15. int * string list fsharp
- 16. c#string [] to jquery string list?
- 17. html select option into a list
- 18. FacebookID String到BigInt Java和Parse
- 19. Java:How to Parse String to Date correct?
- 20. Java string to xml to list
- 21. Haskell String to Maybe List
- 22. Haskell int list to String
- 23. VB.NET List(Of String)(「System.NullReferenceException」)
- 24. List <string> binding
- 25. SQL INSERT INTO with SELECT&string
- 26. 如何將List(List [String])轉換爲Map [String,Int]?
- 27. List <Map <String,String >> vs List <Object>
- 28. 如何將List [String]轉換爲List [ServerAddress]?
- 29. Python「string-or-string-list」類型約定?
- 30. Post Map <String,List <String>>
謝謝,這看起來很酷!在gitter頻道中,已經提到https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists.scala#L2815,是否有可能使用它和跳過寫你自己的TC? – Reactormonk
我認爲'LiftAll'可以給我們Parse [Int] :: Parse [Boolean] :: Parse [Double] :: HNil',但我不確定我們如何使用它來解析'List [String] '? –
我根據'List [String] => String :: String :: String :: HNil'的方法計算了一些東西,用'LiftAll'中的'HList'對其進行壓縮,然後通過驗證遍歷它。 – Reactormonk