简体   繁体   中英

Is there something like Map.keySet for a partial function in scala?

More specifically, I have:

case class Key (key: String)
abstract class abstr {
  type MethodMap = PartialFunction[Key,  String => Unit]
  def myMap: MethodMap // abstract

  def useIt (key: Key, value: String) = {
    val meth = myMap(key)
    meth(value)
  }

  def report = {
    for (key <- myMap.keySet) // how to do this
      println("I support "+key)
  }
}

I use it like this:

class concrete extends abstr {
  var one: Boolean
  def method1(v: String): Unit = ???
  def method2(v: String): Unit = ???

  def map1: MethodMap = {
    case Key("AAA") => method1
  }
  def map2: MethodMap = {
    case Key("AAA") => method2
  }

  override def myMap: MethodMap = if (one) map1 else map2
}

Of course, this is somewhat simplified, but the report function is necessary.

Some history: I first had it implemented using Map but then I changed it to PartialFunction in order to support the following override def myMap: MethodMap = if (one) map1 else map2 .

Any suggestion to refactor my code to support everything is also appreciated.

No. PartialFunction can be defined (and often is) on infinite sets. Eg what do you expect report to return in these situations:

class concrete2 extends abstr {
  def myMap = { case Key(_) => ??? }
}

or

class concrete2 extends abstr {
  def myMap = { case Key(key) if key.length > 3 => ??? }
}

? If you have a finite list of values you are interested in, you can do

abstract class abstr {
  type MethodMap = PartialFunction[Key,  String => Unit]
  def myMap: MethodMap // abstract
  val keys: Seq[Key] = ...

  def report = {
    for (key <- keys if myMap.isDefined(key))
      println("I support "+key)
  }
}

Some history: I first had it implemented using Map but then I changed it to PartialFunction in order to support the last line in second part.

Why? This would work just as well with Map .

In your solution, is there any way to define the domain of the partial function to be the finite set keys

def f: MethodMap = { case key if keys.contains(key) => ... }

Of course, the domain isn't part of the type.

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