2012-03-24 2 views
1

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

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. Есть ли способ добиться аналогичного результата или мне нужно сделать две отдельные карты?

+3

Сделать тривиальную иерархию случая класса вместо просто введите синонимы. –

+0

А, да, и используйте специальный метод 'apply' правильно? Я попробую это. – noncom

+0

Нет, Scala не понимает, что класс с одним методом apply() может быть создан как '() => doSomething()' ... Как печально ... – noncom

ответ

2

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

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 сек в newtype с).

2

я довольно много такое же решение, я должен упростить условие типа, добавив вызов параметр имени и изменение карты быть изменчивыми:

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() 
} 
} 
+0

Вы можете попробовать код в следующих строках: def b (x: => Условие) = {if (x == true) print ("test")} addPair (true, new ComplexReaction (b)) executeAll , но может быть, вам будет лучше иметь кортеж или мультимап, чтобы хранить реакции? – fp4me

Смежные вопросы