In attempting to do validation with application functors (Monad to catch multiple exceptions (not just fail on single)), I came across a hard limit in scalaz that disallows more than 14 functors, so a helpful comment from here (https://github.com/scalaz/scalaz/issues/504#issuecomment-23626237) navigated me to use HLists instead of applicative functors
Now it works perfectly fine (after having to manually put in this sequence file from here since its not in maven https://github.com/typelevel/shapeless-contrib/blob/master/scalaz/main/scala/sequence.scala?source=c)
My question is, and I know this is possible, how would you go about automatically instantiating the case class Foo(i:Int,s:String)
without having to manually match the pattern with a case, only to just reapply the parameters again
Essentially I want to do something like this
case class Foo(i:Int,s:String)
implicit def TwoFoo = Iso.hlist(Foo.apply _, Foo.unapply _)
val someFoo = sequence(
1.successNel[Int] ::
"2".successNel[String] ::
HNil
).map { Foo.apply _} // Note this doesn't work
someFoo match {
case Success(a) => println(a)
case Failure(a) => {
println("failure")
println(a)
}
}
First for a minor point: the type parameter for successNel
is the error type, not the success type, so it needs to be the same across all the arguments to sequence
.
So we can write the following (assuming our errors are strings):
import shapeless._, contrib.scalaz._
import scalaz._, syntax.validation._
case class Foo(i: Int, s: String)
implicit val fooIso = Iso.hlist(Foo.apply _, Foo.unapply _)
val valHList = sequence(1.successNel[String] :: "2".successNel[String] :: HNil)
This gives us an Int :: String :: HNil
inside a validation. Now we can use our isomorphism:
scala> valHList.map(fooIso.from)
res0: scalaz.Validation[scalaz.NonEmptyList[String],Foo] = Success(Foo(1,2))
No need to deconstruct the list and apply the Foo
constructor manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With