[英]Existential types in Scala
请在下面找到一个使我感到困惑的简短示例。
我必须承认,在Scala中操纵存在类型存在一些困难。
我应该如何解决类型不匹配的第56行? 提议者可以__1类型,而提议者可以__1类型<:个人
提前致谢,
class Individual(n: String) {
protected val name=n
var preferred: Individual = this
override def toString(): String=name
}
class Man(n: String) extends Individual(n) { }
class Woman(n: String) extends Individual(n) { }
class Marriage(m: Man, w: Woman){
private val man=m
private val woman=w
def this(w: Woman, m: Man) = this(m,w)
override def toString(): String = man+"--"+woman
}
class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list = m ::list }
override def toString(): String= {
var s: String = ""
for (elm<-list) s=s+elm+" "
return s
}
}
object Test{
protected var male = true
def main(args: Array[String]): Unit = {
val al = new Man("Al")
val bob = new Man("Bob")
val alice = new Woman("Alice")
val barbara = new Woman("Barbara")
al.preferred = alice
bob.preferred = barbara
alice.preferred = bob
barbara.preferred = al
val men = Set(al, bob)
val women = Set(alice, barbara)
val m = new Matching()
//var proposers=women
var proposers: Set[_ <:Individual] = Set[Individual]()
if (male) proposers = men
else proposers = women
while (!proposers.isEmpty) {
for(proposer <- proposers) {
val proposer=proposers.head
if (proposer.isInstanceOf[Man])
m.add(new Marriage(
proposer.asInstanceOf[Man],
proposer.preferred.asInstanceOf[Woman]
))
else
m.add(new Marriage(
proposer.asInstanceOf[Woman],
proposer.preferred.asInstanceOf[Man]
))
proposers-=proposer//There is an error here
}
}
println(m)
}
}
这段代码很乱。 它的格式不正确,混合了制表符和空格,即使在功能解决方案几乎不需要思考的最琐碎的地方,它也使用可变性。
该法规也无法在国际上推广到可能发生同性婚姻的国家。
从上到下工作...
我怀疑您永远都不想直接实例化一个Individual
,只是一个Man
或一个Woman
。 因此,代数数据类型更有意义,这是通过sealed trait
和case class
子类型完成的。
我还将删除preferred
属性,因为它可能导致循环引用。 处理不可变数据超出了我在这个答案中愿意达到的水平。
sealed trait Individual {
def name: String
override def toString(): String=name
}
//as it's a case class, `name` becomes a val,
//which implements the abstract `def name` from the trait
case class Man(name: String) extends Individual
case class Woman(name: String) extends Individual
Marriage
也可以是一个案例类,让我们将类参数的笨拙重复放入val中-这只是毫无意义的样板。 这也是将辅助构造函数移动到伴随对象中的工厂方法的好时机:
case class Marriage(man: Man, woman: Woman) {
override def toString(): String = man + "--" + woman
}
object Marriage {
def apply(w: Woman, m: Man) = new Marriage(m,w)
}
Matching
几乎没有意义,整个类只是包装一个List
? 在前泛型Java中,这种事情很有意义,但现在已经不复存在了。 我仍将保留它(暂时),以便我可以修复该toString
实现,该实现很痛苦地易变,并且没有充分的理由使用return
:
case class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list ::= m }
override def toString() = list.mkString(" ")
}
最后是“肉”的问题。 评论是内联的,但您会注意到我不需要(或使用) Matching
。 最后的println
完全取代了它
object Test{
//better name, and a val (because it never changes)
protected val menPropose = true
def main(args: Array[String]): Unit = {
// `new` not required for case classes
val al = Man("Al")
val bob = Man("Bob")
val alice = Woman("Alice")
val barbara = Woman("Barbara")
// remember how preference was removed from `Individual`?
val mprefs = Map( al -> alice, bob -> barbara )
val fprefs = Map( alice -> bob, barbara -> al )
val men = Set(al, bob)
val women = Set(alice, barbara)
// nicely immutable, and using the returned value from if/else
val proposers = if (menPropose) men else women
// no while loop, name shadowing, or mutability.
// just a simple for-comprehension
val marriages = for(proposer <- proposers) yield {
//pattern-matching beats `isInstanceOf`... every time
proposer match {
case m: Man => Marriage(m, mprefs(m))
case f: Woman => Marriage(f, fprefs(f))
}
}
println(marriages mkString " ")
}
}
还有更多可以在这里完成的方法。 什么是同性关系? 如果两个或两个以上的人拥有相同的偏好怎么办? 如果某人没有偏好怎么办?
我还可以将某人的偏好类型编码为Individual
实例。 但这已经变得更加先进。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.