[英]Scala: How to transform an HList of ValidatedNel into a ValidatedNel of HList
I've been using cats.data.Validated
successfully to solve the problem below, but have come into a problem using my existing solution for a case class with more than 22 members (because the constructor cannot be made into a Function
). 我一直在成功使用cats.data.Validated
解决以下问题,但是使用我现有的解决方案解决了一个包含22个以上成员的case类的问题(因为无法将构造方法构造为Function
)。
Here is my goal: generate a bunch of ValidatedNel[E, T]
, sequence them into a ValidatedNel[E, (T1, T2, ...)]
, then mapN(DAOClass)
(where DAOClass
is a case class
with the specified arguments). 这是我的目标:生成一堆ValidatedNel[E, T]
,将它们排序为ValidatedNel[E, (T1, T2, ...)]
,然后是mapN(DAOClass)
(其中DAOClass
是具有指定条件的case class
参数)。 This works for fewer than 22 arguments, but fails with more because of two problems: 此方法适用于少于22个参数,但由于两个问题而失败了,但失败了:
(T1, T2, ...)
cannot have more than 22 components (T1, T2, ...)
不能有超过22个组件 DAOClass.apply
cannot be transformed into a Function
DAOClass.apply
无法转换为Function
So I am looking into using shapeless.HList
to handle part 1 and having problems. 因此,我正在研究使用shapeless.HList
处理第1部分并遇到问题。 I should be able to use Generic[DAOClass]
to satisfactorily handle part 2 when I get to it, or if that doesn't work, use extensible records with a bit more boilerplate. 我应该能够使用Generic[DAOClass]
满意地处理第2部分,否则,如果不起作用,请使用可扩展的记录 ,并增加一些样板。
Here is some small example code (not with 22 components): 这是一些小的示例代码(不包含22个组件):
package example
import cats.syntax.validated._
import cats.data.ValidatedNel
import cats.sequence._
import shapeless._
case class DAOClass(a: Int, b: Int)
object DAOClass {
def generate: ValidatedNel[String, DAOClass] = {
val hlist: ValidatedNel[String, Int] :: ValidatedNel[String, Int] :: HNil =
1.validNel :: 2.validNel :: HNil
val hlistSequence: ValidatedNel[String, Int :: Int :: HNil] = hlist.sequence
hlistSequence.map(Generic[DAOClass].from)
}
}
This uses the kittens
library to sequence the HList
. 这使用kittens
库对HList
。
Unfortunately, this gives me a compile error: 不幸的是,这给了我一个编译错误:
[error] ...src/main/scala/example/DAOClass.scala:17:73: cannot construct sequencer, make sure that every item of your hlist shapeless.:: [cats.data.ValidatedNel[String,Int],shapeless.::[cats.data.ValidatedNel[String,Int],shapeless.HNil]] is an Apply
[error] val hlistSequence: ValidatedNel[String, ::[Int, ::[Int, HNil]]] = hlist.sequence
[error] ^
I have extracted this into a test project; 我已经将其提取到一个测试项目中; here's my build.sbt
: 这是我的build.sbt
:
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.12.6",
version := "0.1.0-SNAPSHOT"
)),
name := "shapeless-validation",
resolvers ++= Seq(
Resolver.sonatypeRepo("releases")
),
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.3",
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
"org.typelevel" %% "cats-core" % "1.1.0",
"org.typelevel" %% "kittens" % "1.1.0"
)
)
What am I missing? 我想念什么? Do I need to import more implicits somewhere? 我是否需要在某个地方导入更多隐式内容? Is there a better way to do this? 有一个更好的方法吗?
You forgot to add 你忘了加
scalacOptions += "-Ypartial-unification"
to build.sbt
. 建立build.sbt
。 For normal work with cats
this is usually mandatory. 对于cats
正常工作,这通常是强制性的。
Now 现在
hlistSequence.map(Generic[DAOClass].from)
produces a ValidatedNel[String, DAOClass]
: 产生一个ValidatedNel[String, DAOClass]
:
println(DAOClass.generate) // Valid(DAOClass(1,2))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.