在学习时Scalaz 6,我正在尝试编写返回验证的类型安全的读取程序。这里是我的新类型:如何使用scalaz编写应用程序的功能
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
更新:以下是编译器错误消息试图行了,当上面或丹尼尔建议,我得到:
[error] ***/MapReader.scala:114: type mismatch;
[error] found : scalaz.Validation[scalaz.NonEmptyList[String],String]
[error] required: String
[error] val boy = (name |@| age) { Boy(_,_) }
[error] ^
我以后会发布一个答案,但作为一个提示,请记住, 'Applicative [G]'和'Applicative [F]'意味着'Applicative [[x] F [G [x]]'。在scalaz 7中,'Applicative#compose'证明了这个事实。首先直接使用类型类,而不是使用'| @''语法。 – retronym 2012-02-23 07:58:38
谢谢,但我仍然不明白,所以我会等待你的回答。请注意,我正在使用scalaz 6(问题已更新)。 – paradigmatic 2012-02-23 08:05:25
@paradigmatic你有没有试过明确使用'apply'?像'(name | @ | age)应用{Boy(_,_)}'? – 2012-02-23 13:59:01