如何在Scala中获取部分函数的域?

时间:2012-03-04 21:14:40

标签: scala functional-programming

是否可以在Scala中获取部分函数的域?

例如:

    val f: PartialFunction[Int, Unit] = {

      case 1 => println("This is 1")

      case 2 => println("This is 2")

   }

有没有办法得到类似的东西:

    val list = f.getDomain

表示值1和2?

更新:我正在尝试构建通知系统(事件总线)。 订阅者将如下所示:

    class SomeSubscriber extends Subscriber {

    notifications {

      case LoginEvent(date) => println("Login on " + date)

      case LogoutEvent(date) => println("Logout on " + date)

      case e: Notification[Any] => async {

         println("Other notification: " + e)

         ui {

          println("UI in async! " + e)

         }

       }

     }

   }

在我的NotiticationService(事件调度程序)中,我想访问在每个“通知”块中声明的事件,以便我可以将通知推送给订阅者。我怎么能这样做?

提前致谢。

3 个答案:

答案 0 :(得分:11)

如果您有一个集合,并且您想知道哪些元素也属于f的域名,则可以使用filterisDefinedAt,如下所示:

scala> 1 to 10 filter f.isDefinedAt
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2)

这只是详尽地检查。我不知道是否有更好的方法。

答案 1 :(得分:4)

这本身是不可能的,因为可以为输入范围的任何子集定义部分函数;输入范围本身可能不是有限的,在这种情况下,域也不一定是有限的。您只能通过详尽的匹配获得域名(根据Dan的答案),但是您不能穷尽地搜索无限的输入空间。

答案 2 :(得分:0)

对不起六年的延误。

我不相信这个问题可以用地图来解决。通知的格式为:

case LoginEvent(date) => ...

涉及一个包含变量日期的模式,其值在编译时是未知的:当模式在执行期间匹配时,它将被绑定。

您实际上不需要域值的列表(或集)。你想知道模式,就像我看到的那样。

我也遇到过这个问题,虽然它可能不是一个常见问题,但是它确实潜入了Scala中反射的角色:从程序中检查代码的能力。它涉及浅层和深层内部DSL之间的区别。上面的DSL很浅,导致无法分析代码的问题。