Som*_*kar 13 scala polymorphic-functions
在Scala MEAP v10中的功能编程一书中,作者提到了这一点
多态函数通常受其类型约束,因此它们只有一个实现!
并举例说明
def partial1[A,B,C](a: A, f: (A,B) => C): B => C = (b: B) => f(a, b)
Run Code Online (Sandbox Code Playgroud)
这句话是什么意思?多态函数是否具有限制性?
Jör*_*tag 20
这是一个更简单的例子:
def mysteryMethod[A, B](somePair: (A, B)): B = ???
Run Code Online (Sandbox Code Playgroud)
这种方法有什么作用?事实证明,这种方法只能做一件事!您不需要方法的名称,您不需要执行该方法,您不需要任何文档.该类型告诉你它可能做的一切,事实证明在这种情况下"一切"只是一件事.
那么,它做了什么?它需要一对(A, B)并返回一些类型的值B.它返回什么价值?它可以构造一个类型的值B吗?不,它不能,因为它不知道是什么B!它可以返回类型的随机值B吗?不,因为随机性是副作用,因此必须出现在类型签名中.它可以在宇宙中出现并获取一些B吗?不,因为这会产生副作用,并且必须出现在类型签名中!
实际上,它唯一能做的就是返回B传递给它的类型的值,这是该对的第二个元素.所以,这mysteryMethod真的是second方法,它唯一明智的实现是:
def second[A, B](somePair: (A, B)): B = somePair._2
Run Code Online (Sandbox Code Playgroud)
请注意,实际上,由于Scala既不是纯粹的也不是完全的,实际上该方法还可以执行其他一些操作:抛出异常(即异常返回),进入无限循环(即根本不返回),使用反射以找出实际类型B并反射调用构造函数来构造新值等.
但是,假设纯度(返回值可能只取决于参数),totality(方法必须正常返回一个值)和参数(它实际上并不知道任何关于A和B),那么实际上你可以有很多通过仅查看其类型来讲述方法.
这是另一个例子:
def mysteryMethod(someBoolean: Boolean): Boolean = ???
Run Code Online (Sandbox Code Playgroud)
这有什么作用?它总是可以返回false并忽略它的论点.但是它会受到过度约束:如果它总是忽略它的论点,那么它并不关心它是一个Boolean它的类型宁愿是
def alwaysFalse[A](something: A): Boolean = false // same for true, obviously
Run Code Online (Sandbox Code Playgroud)
它总是可以只返回它的论点,但是再一次,它实际上并不关心布尔值,它的类型宁愿
def identity[A](something: A): A = something
Run Code Online (Sandbox Code Playgroud)
所以,真的,它唯一能做的就是返回一个不同于传入的布尔值,因为只有两个布尔值,我们知道我们的mysteryMethod实际上是not:
def not(someBoolean: Boolean): Boolean = if (someBoolean) false else true
Run Code Online (Sandbox Code Playgroud)
所以,在这里,我们有一个例子,这里的类型不给我们的实现,但至少,他们给的(小)组的4级可能的实现,其中只有一个是有道理的.
(顺便说一句:事实证明,只有一种方法的可能实现,它接受A并返回一个A,并且它是上面显示的身份方法.)
所以,回顾一下:
将您的参数视为机器的一部分,将您的类型视为这些机器部件上的连接器.只有有限数量的方法可以将这些机器部件连接在一起,只需将兼容的连接器插在一起,并且没有任何剩余部件.通常情况下,只有一种方式,或者如果有多种方式,那么通常一种方式显然是正确方式.
这意味着,一旦你设计了对象和方法的类型,你甚至不必考虑如何实现这些方法,因为类型已经规定了实现它们的唯一可能方法!考虑StackOverflow上有多少的问题基本上都是"我怎么实现这一点?",你可以想像释放它必须没有怎么考虑这个问题的所有,因为该类型已经决定了一个(或几个之一)可能实现?
现在,看看在你的问题的方法的签名,并尝试用不同的方式来结合玩耍a,并f以这样的方式,该类型的排队,同时使用a和f,你的确会看到,只有一个做到这一点的方法.(正如克里斯和保罗所示.)
def partial1[A,B,C](a: A, f: (A,B) => C): B => C = (b: B) => f(a, b)
Run Code Online (Sandbox Code Playgroud)
这里,partial1作为类型A的参数值,以及采用类型A的参数和类型B的参数的函数,返回类型C的值.
partial1必须返回一个取B型值并返回C的函数.鉴于A,B和C是任意的,我们不能对它们的值应用任何函数.所以唯一的可能性是将函数f应用于a传递给partial的值,以及类型B的值,它是我们返回的函数的参数.
所以你最终得到了定义中的单一可能性 f(a,b)
| 归档时间: |
|
| 查看次数: |
368 次 |
| 最近记录: |