简体   繁体   中英

Scala - make custom types covariant

I want to make two custom types with the type keyword and make them covariant to some other type, so that I could put them both in one list or map and work with it through pattern-matching, is that possible?

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

but of course that kind of type construct is not allowed in Scala. Is there any way to acheive a similar result or do I have to make two separate maps?

This is one possibly good way.

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

As a side note, this is what I would normally do in Haskell (change any conflicting type s into newtype s).

i have pretty much the same solution, i have simplify the type Condition , adding call by name parameter and change map to be mutable :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM