我有以下 Scala / Play!代码:
case class Tweet(from: String, text: String)
implicit val tweetReads = (
(JsPath \ "from_user_name").read[String] ~
(JsPath \ "text").read[String]) (Tweet.apply _)
我有关于上述代码的语法和含义的几个问题:
~
方法?Tweet.apply
的参数的类/类型是什么?编辑1 :完整的源代码:
package models
import play.api.libs.json._
import play.api.libs.json.util._
import play.api.libs.json.Reads._
import play.api.libs.json.Writes._
import play.api.libs.functional.syntax._
case class Tweet(from: String, text: String)
object Tweet {
implicit val tweetReads = (
(JsPath \ "from_user_name").read[String] ~
(JsPath \ "text").read[String])(Tweet.apply _)
implicit val tweetWrites = (
(JsPath \ "from").write[String] ~
(JsPath \ "text").write[String])(unlift(Tweet.unapply))
}
答案 0 :(得分:8)
一步一步:
对象JsPath
上的方法\
val path1: JsPath = JsPath \ "from_user_name"
val path2: JsPath = JsPath \ "text"
read
JsPath
val reads1: Reads[String] = path1.read[String]
val reads2: Reads[String] = path2.read[String]
~
中没有方法Reads
,但FunctionalBuilderOps
中有这样的方法,M[T]
到FunctionalBuilderOps[M[_], T]
的隐式转换{ {3}} - toFunctionalBuilderOps
。
val reads1FunctionalBuilderOps: FunctionalBuilderOps[Reads, String] =
toFunctionalBuilderOps(reads1)
val canBuild2: CanBuild2[String, String] = reads1FunctionalBuilderOps.~(reads2)
Tweet.apply _
是一种使用FunctionN
参数创建N
使用方法的scala语法:
val func: (String, String) => Tweet = Tweet.apply _
apply
中有CanBuild2[A, B]
个方法。它接受(A, B) => C
并返回Reads[C]
(在这种情况下):
implicit val tweetReads: Reads[Tweet] = canBuild2.apply(func)
实际上,JsPath#read
,toFunctionalBuilderOps
和CanBuild2#apply
方法中也存在隐式参数。有了这些参数:
val reads1: Reads[String] = path1.read[String](Reads.StringReads)
...
val reads1FunctionalBuilderOps: FunctionalBuilderOps[Reads, String] =
toFunctionalBuilderOps(reads1)(
functionalCanBuildApplicative(
Reads.applicative(JsResult.applicativeJsResult)))
...
implicit val tweetReads: Reads[Tweet] =
canBuild2.apply(func)(functorReads)
答案 1 :(得分:2)
我想补充一点,这就是所谓的应用语法(对于applicative functors)。例如,可以在scala parser combinator library
中看到它如果您想知道如何使用json尝试阅读this。播放框架中应用仿函数的另一个例子是form handling。或者您可以尝试阅读有关scalaz验证的信息。