在非常有启发性的演讲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
答案 0 :(得分:4)
glib答案是“由多态lambda演算建模的Scala的子集”:)。
{p>不太明显the Scalazzi Safe Scala subset有一个非常好的条件清单。它们仅在下面进行了少量修改。null
_.isInstanceOf
和case
匹配)
_.asInstanceOf
).equals
(_ == _
),.toString
或.hashCode
notify
或wait
(我会混淆副作用)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 class
和case object
形式的编译器提供的提取器。 match is not exhaustive
警告,并且您匹配的内容更好地是sealed
的某个子类型。这些规则与Typelevel博客文章提出的fold
- 编码规则略有不同,但基本相同(上面的规则更保守,希望更容易保留在您的脑海中)。
如果您不能/不想验证这些功能是否适用于您未编写但使用的所有功能,我发现遵循上述规则,您自己的代码然后不依赖于将Any
作为参数,或者生成Unit
作为返回类型通常就足够了。
答案 1 :(得分:0)
声明是正确的,并且如果您将注意力限制在引用透明函数上,则不需要进行子集化。