Al aprender Scalaz 6, intento escribir lectores de tipo seguro que devuelvan las validaciones. Aquí están mis nuevos tipos:Cómo componer la función a los aplicativos con scalaz
type ValidReader[S,X] = (S) => Validation[NonEmptyList[String],X]
type MapReader[X] = ValidReader[Map[String,String],X]
y tengo dos funciones que crean mapa lectores de enteros y cadenas (*):
def readInt(k: String): MapReader[Int] = ...
def readString(k: String): MapReader[String] = ...
se tenga lo siguiente mapa:
val data = Map("name" -> "Paul", "age" -> "8")
I puede escribir dos lectores para recuperar el nombre y la edad:
val name = readString("name")
val age = readInt("age")
println(name(data)) //=> Success("Paul")
println(age(data)) //=> Success(8)
Todo funciona bien, pero ahora quiero componer tanto a los lectores a construir una Boy
ejemplo:
case class Boy(name: String, age: Int)
Mi mejor toma es:
val boy = (name |@| age) {
(n,a) => (n |@| a) { Boy(_,_) }
}
println(boy(data)) //=> Success(Boy(Paul,8))
Funciona como se esperaba, pero la expresión es torpe con dos niveles de constructores aplicativos. ¿Hay alguna forma de que funcione la siguiente sintaxis?
val boy = (name |@| age) { Boy(_,_) }
(*) completa y la aplicación ejecutable en: https://gist.github.com/1891147
Actualización: Aquí es el mensaje de error del compilador que consigo cuando se trata de la línea por encima o por Daniel sugerencia:
[error] ***/MapReader.scala:114: type mismatch;
[error] found : scalaz.Validation[scalaz.NonEmptyList[String],String]
[error] required: String
[error] val boy = (name |@| age) { Boy(_,_) }
[error] ^
Voy a publicar una respuesta más tarde, pero como una sugerencia, recuerde que 'Applicative [G]' and 'Applicative [F]' implica 'Applicative [[x] F [G [x]]'. En scalaz 7, 'Applicative # Componer' es testigo de este hecho. Trabaje directamente con las clases de tipos para comenzar, en lugar de utilizar la sintaxis '| @ |'. – retronym
Gracias, pero todavía no lo entiendo, así que esperaré su respuesta. Tenga en cuenta que estoy usando scalaz 6 (pregunta actualizada). – paradigmatic
@paradigmatic ¿Ha intentado usar 'apply' explícitamente?Al igual que '(name | @ | age) apply {Boy (_, _)}'? –