多态lambda演算

时间:2016-05-06 18:48:14

标签: scala lambda-calculus

在非常有启发性的演讲Constraints Liberate中,Rúnar说,实现具有此签名的函数只有一种方法:

def id[A](a: A): A
显然,很明显。但挑剔的人可能会提出像

这样的实现
def id[A](a: A): A = {
  if (a.isInstanceOf[Integer])  
    5
  else 
    a
}

好的,我为什么要关心?

关于着名的Theorems for free! article中的函数,可以说完全相同的问题,但是我们有functions in the polymorphic lambda calculus的限制,在这种情况下,Type-Casing肯定是无效的。

我正在寻找一种精确的方法来清楚地说明当我们说像这样的东西时,允许使用Scala语言的哪个子集:“只有一个带有此签名的纯函数的可能实现:” < / p>

def id[A](a: A): A

2 个答案:

答案 0 :(得分:4)

glib答案是“由多态lambda演算建模的Scala的子集”:)。

{p>不太明显the Scalazzi Safe Scala subset有一个非常好的条件清单。它们仅在下面进行了少量修改。

  • null
  • 无例外
  • 除了一个例外
  • 之外,没有类型框(_.isInstanceOfcase匹配)
  • 没有类型转换(_.asInstanceOf
  • 无副作用
  • .equals_ == _),.toString.hashCode
  • notifywait(我会混淆副作用)
  • classOf.getClass
  • 没有一般递归(更常见的是所有函数必须是总计)

“无类型套管”的一个例外是pattern matching with match ... case on the equivalent of algebraic data types with sealed hierarchies and case classes and case objects。要知道您的特定match ... case语句是否被允许,请使用以下规则:

  • 仅在case语句中使用提取器;不要使用case (x: Int)...类型匹配。确保您的提取器符合Scalazzi规则(实现此目的的最简单方法是根本不编写提取器,即仅使用case classcase object形式的编译器提供的提取器。
  • 比赛必须涵盖所有可能的情况。这意味着没有match is not exhaustive警告,并且您匹配的内容更好地是sealed的某个子类型。

这些规则与Typelevel博客文章提出的fold - 编码规则略有不同,但基本相同(上面的规则更保守,希望更容易保留在您的脑海中)。

如果您不能/不想验证这些功能是否适用于您未编写但使用的所有功能,我发现遵循上述规则,您自己的代码然后不依赖于将Any作为参数,或者生成Unit作为返回类型通常就足够了。

答案 1 :(得分:0)

声明是正确的,并且如果您将注意力限制在引用透明函数上,则不需要进行子集化。