【发布时间】:2016-08-11 01:44:57
【问题描述】:
我试图了解类型别名的工作原理以及扩展,一个以type Set = Int => Boolean 为模型的简单Set 类型将如何被重写为具有部分函数的类。
背景:我知道我可以像上面一样创建类型别名,并将其用作简单的函数集数据类型:
type Set = Int => Boolean
def union(s: Set, t: Set): Set = (x => s(x) || t(x))
def contains(s: Set, n: Int): Boolean = s(n)
val s1 = Set(3)
val s2 = Set(7)
val u1 = union(s1, s2)
contains(u1, 3) // res4: Boolean = true
一切顺利。需要一些思考,但我知道它是如何工作的; u1
本质上变成了一个偏函数,基于:
union(s: (Int => Boolean), t: (Int => Boolean)): Int => Boolean
所以如果我想把它变成一个类,我的第一次尝试是这样的:
case class Set(v: Int) {
def apply(i: Int) = i == v
def contains(n: Int): Boolean = this(n)
def union(n: Set): Set = (x => n(x) || apply(x)) // Missing param
}
但这不起作用(union 的定义有编译错误,x 是缺少参数)。
在摆弄了一段时间之后,我不知道如何在不采用更命令式的方法(例如实际创建基于集合的 Set 类)的情况下实现类似的类型。必须有一种方法可以以纯粹的功能方式做到这一点......
【问题讨论】:
-
我看不到不诉诸面向对象的方法来实现您想要的。
union的问题在于它应该是一个 Set,但它被定义为一个函数。为了使它成为一个 Set,我们需要一个 Set 的扩展实例,其中 apply 可以满足任何集合,这几乎违背了基于函数的实现的要点。 -
类型别名仅通过替换起作用。
-
我认为您的范围内有 3 个 Set 定义,哈哈... xD 1. 您的类型别名
Set(function), 2. val s1 = Set(3) (scala.Set) 3. 你的case class Set。并不奇怪它不起作用......不,联合不是一个偏函数。 -
另外,这是一项来自(Scala 中的 FP)[coursera.org/learn/progfun1] 的任务,所以我们不应该根据learner.coursera.help/hc/en-us/articles/… 来回答它。
-
以上是两个不同的(例如不一起编译)代码块。这也是 Programming Scala 书中介绍的一个主题,我正试图更彻底地理解它......是的,在 Odersky 的课堂上重新引入,我已经 100% 毕业了......不,不相关。
标签: scala type-alias