在多态性不足的情况下为什么实现`List a - >的方法较少?列出一个 - >列出a`然后`列表字符 - >列表字符 - >列出Char`

时间:2016-10-14 12:46:05

标签: scala functional-programming

insufficiently-polymorphic

中的

作者说: def foo[A](fst: List[A], snd: List[A]): List[A]

  

我们实现该功能的方式较少。特别是我们   不能只是对列表中的某些元素进行硬编码,因为我们没有   能够制造任意类型的价值。

我不理解这一点,因为在[Char]版本中我们也无法制作任意类型的值,我们必须使用类型为[Char]的类型,所以为什么实现的方法较少此?

3 个答案:

答案 0 :(得分:5)

在通用版本中,您知道输出列表只能包含fstsnd中包含的元素的某些排列,因为无法构造某些任意类型的新值{{1 }}。相反,如果你知道输出类型是A,你可以例如。

Char

此外,您不能使用输入列表中包含的值来做出影响输出的决策,因为您不知道它们是什么。如果您知道输入类型,则可以执行此操作,例如

def foo(fst: List[Char], snd: List[Char]) = List('a', 'b', 'c')

答案 1 :(得分:3)

我假设作者的意思是,没有办法构建非空List a但是有一种方法可以构建List Char,例如通过使用字符串文字。你可以忽略参数,只返回一个硬编码的字符串。 这方面的一个例子是:

foo :: List Char -> List Char -> List Char
foo a b = "Whatever"

您无法构造任意类型a的值,但您可以构造Char类型的值。

答案 2 :(得分:2)

这是一个名为"parametricity"或“自由定理”的属性的简单情况,它适用于每个多态函数。

更简单的例子如下:

fun1 :: Int -> Int
fun2 :: forall a. a -> a

fun1可以是任何东西:后继者,前任者,正方形,阶乘法等。这是因为它可以“读取”其输入,并采取相应的行动。

fun2 必须是身份功能(或永远循环)。这是因为fun2接收了它的输入,但它无法以任何有用的方式检查它:因为它是一个抽象的未知类型a,所以不能对它执行任何操作。输入实际上是一个不透明的令牌。 foo2的输出必须是a类型,我们不知道任何构造方法 - 我们无法从零开始创建类型a的值。唯一的选择是获取输入a并使用它来制作输出a。因此,fun2是身份。

当您无法对输入或类型a执行测试时,上述参数化结果成立。如果我们(例如,允许if x.instanceOf[Int] ...if x==null ...或类型转换(在OOP中),那么我们可以用其他方式编写fun2