【发布时间】:2016-01-20 23:53:16
【问题描述】:
在 Scala (Play Framework) 中,即使我阅读了 here 中的所有符号,我也无法理解类型签名。
例如:
/* matches if a == b */
def equalTo[T](t: => T): BeEqualTo
class BeEqualTo(t: => Any)
extends BeTypedEqualTo[Any]
这些类型签名到底意味着什么?
例如,文档中的“a”和“b”到底是什么?我看到的只是“t”。 equalTo 是一个函数,它接受一个返回泛型类型 T 值的函数?
另一个例子...
假设我有这条线...
status(home).must(equalTo(OK))
根据 IDE,OK 是 Int 类型的模式或符号。那么可以是 Int 吗?你可以给一个 int 打猴子补丁,给它一个像“must”这样的函数,但是一个 Int 怎么能进入“equalTo”,一个接受函数的函数呢?
现在一些类型签名是有意义的。比如……
def status(of: Future[Result])(implicit timeout: Timeout): Int
^ 这是一个柯里化函数,它接收一个返回 Result 类型的东西的未来,它从某个地方(Scala 魔法)吸入一个 Timeout 类型的隐式参数并返回一个 Int。 “home”的类型是“Future[Result]”,所以它适合“status”。
但其他的东西......
contentType(home).must(beSome.which(_ == "text/html"))
^ 我的 IDE 说 beSome 属于
def beSome[T](check: ValueCheck[T]): SomeCheckedMatcher[T]
^ 所以“beSome”是一个函数。如果是这样的话,那我到底怎么能把另一个函数“.which()”当作一个对象来附加它呢?
另一个例子...
def which[R : AsResult](f: (U) => R): OptionLikeCheckedMatcher[F, Nothing, U]
^ 你到底是如何阅读这些类型签名的? “which”接受“f: (U)”,还是我们称之为“(U)”类型的“f”的变量?为什么“(U)”周围有不必要的括号?如果 R 是字符串,你不能只说 "f: U" 并让 U 成为字符串吗?
“必须”是这样的……
def must(m: => Matcher[T]): MatchResult[T]
^ 所以“必须”接受一个返回匹配器的函数。但是“which”传入了一个 OptionLikeCheckedMatcher。 "m: => Matcher[T]" 是一个接受 "m" 并返回 "Matcher[T]" 的函数。这与 OptionLikeCheckedMatcher 类型的对象有何相同之处?
有人可以提供关于如何阅读 Scala 类型签名的权威指南吗?
【问题讨论】:
-
您的问题太长,无法给出完整的答案,但是,我可以告诉您的一件事是“不要太相信 IDE”,尤其是在您编写 Scala 时。对于
beSome,有两个声明,一个参数没有参数。 etorreborre.github.io/specs2/api/SPECS2-2.3.12/… -
所以 _ == "text/html" 是一个带有通用参数 "" 的函数。这个函数被传递给“which”,它是 SomeMatcher[T] 内部的一个字段,调用无参数“beSome”函数后的返回类型。 which 函数在 {} 中接受这个匿名函数并返回一个 OptionLikeCheckedMatcher[Option, String, String] 或 OptionLikeCheckedMatcher[F, Nothing, String] (我真的不知道),但是匿名中的“”函数是一个字符串。
标签: scala playframework playframework-2.0