Scala - сделать пользовательские типы ковариантными - PullRequest
1 голос
/ 24 марта 2012

Я хочу создать два пользовательских типа с ключевым словом type и сделать их ковариантными по отношению к другому типу, чтобы я мог поместить их обоих в один список или карту и работать с ним посредством сопоставления с образцом, возможно ли это?

type Reaction

type Condition = () => Boolean

type ComplexReaction extends Reaction = (Condition) => Unit
type SimpleReaction extends Reaction = () => Unit

val map = Map[Condition, Reaction]

def addPair(c: Condition, a: Reaction) { map += (c -> a) }

def executeAll {
  for(puffy <- map) puffy match {
    case (c, a: ComplexReaction) => a(c)
    case (c, a: SimpleReaction) => if(c) a()
  }
}

но, конечно, такого рода конструкция type недопустима в Scala.Есть ли способ получить аналогичный результат или мне нужно сделать две отдельные карты?

Ответы [ 2 ]

2 голосов
/ 24 марта 2012

У меня почти такое же решение, я упростил тип Condition, добавив параметр call by name и изменив карту на изменяемую:

type Condition = Boolean

sealed abstract class Reaction

case class ComplexReaction(rec: (=> Condition) => Unit) extends Reaction

case class SimpleReaction(rec: () => Unit)  extends Reaction 


var map = Map[Condition, Reaction]()

def addPair(c: Condition, a: Reaction) { map += (c -> a) }

def executeAll {
for(puffy <- map) puffy match {
case (c, ComplexReaction(i)) => i(c)
case (c, SimpleReaction(i)) => if(c) i()
}
}
2 голосов
/ 24 марта 2012

Это, возможно, хороший способ.

type Condition = () => Boolean

sealed trait Reaction
case class ComplexReaction(a: (Condition) => Unit) extends Reaction
case class SimpleReaction(a: () => Unit) extends Reaction

val map = Map[Condition, Reaction]

def addPair(c: Condition, a: Reaction) { map += (c -> a) }

def executeAll {
  for(puffy <- map) puffy match {
    case (c, ComplexReaction(a)) => a(c())
    case (c, SimpleReaction(a)) => if(c()) a()
  }
}

В качестве примечания, это то, что я обычно делаю в Haskell (измените любые конфликтующие type s на newtype s).

...