在学习Scalaz 6时,我正在尝试编写返回验证的类型安全阅读器。这是我的新类型:
type ValidReader[S,X] = (S) => Validation[NonEmptyList[String],X]
type MapReader[X] = ValidReader[Map[String,String],X]
我有两个函数为整数和字符串(*)创建地图阅读器:
def readInt( k: String ): MapReader[Int] = ...
def readString( k: String ): MapReader[String] = ...
给定以下地图:
val data = Map( "name" -> "Paul", "age" -> "8" )
我可以写两个读者来检索姓名和年龄:
val name = readString( "name" )
val age = readInt( "age" )
println( name(data) ) //=> Success("Paul")
println( age(data) ) //=> Success(8)
一切正常,但现在我想组合两个读者来构建一个Boy
实例:
case class Boy( name: String, age: Int )
我最好的看法是:
val boy = ( name |@| age ) {
(n,a) => ( n |@| a ) { Boy(_,_) }
}
println( boy(data) ) //=> Success(Boy(Paul,8))
它按预期工作,但是对于两个级别的应用程序构建器来说,表达方式很尴尬。有没有办法让以下语法起作用?
val boy = ( name |@| age ) { Boy(_,_) }
(*) 完整且可运行的实现:https ://gist.github.com/1891147
更新:这是我在尝试上述行或 Daniel 建议时收到的编译器错误消息:
[error] ***/MapReader.scala:114: type mismatch;
[error] found : scalaz.Validation[scalaz.NonEmptyList[String],String]
[error] required: String
[error] val boy = ( name |@| age ) { Boy(_,_) }
[error] ^