Scala匹配变量的函数

时间:2014-03-04 15:26:37

标签: scala jvm pattern-matching

当我匹配案例类的值时,例如:

sealed abstract class Op
case class UOp[T, K](f: T => K) extends Op
case class BOp[T, Z, K](f: (T, Z) => K) extends Op
像这样:

def f(op: Op): Int =
op match
{
    case BOp(g) => g(1,2)
    case UOp(g) => g(0)
}

编译器将其推断为

val g: (Nothing, Nothing) => Any
val g: Nothing => Any

为什么我没有这样的类型?是因为JVM类型擦除吗?有没有优雅的方法来匹配函数与变量?

1 个答案:

答案 0 :(得分:1)

我提出了这种“hackish”解决方案,也许还有其他方法或更简洁的方法可以做到这一点,而不依赖于反射。

定义一些将处理各种args的部分函数:

scala> val f: PartialFunction[Any, String] = { case (x: Int, y: String) => y * x }
f: PartialFunction[Any,String] = <function1>

scala> val g: PartialFunction[Any, String] = { case x: Int => x.toString }
g: PartialFunction[Any,String] = <function1>

scala> def h: PartialFunction[Any, BigDecimal] = { case (a: Int, b: Double, c: Long) => BigDecimal(a) + b + c }
h: PartialFunction[Any,BigDecimal]

scala> val l: List[PartialFunction[Any, Any]] = f :: g :: h :: Nil
l: List[PartialFunction[Any,Any]] = List(<function1>, <function1>, <function1>)

检查哪些功能可以处理不同的输入:

scala> l.map(_.isDefinedAt(1))
res0: List[Boolean] = List(false, true, false)

scala> l.map(_.isDefinedAt((1, "one")))
res1: List[Boolean] = List(true, false, false)

给定输入查找并应用函数:

scala> def applyFunction(input: Any): Option[Any] = {
     |   l find (_.isDefinedAt(input)) map (_ (input))
     | }
applyFunction: (input: Any)Option[Any]

scala> applyFunction(1)
res1: Option[Any] = Some(1)

scala> applyFunction((2, "one"))
res2: Option[Any] = Some(oneone)

scala> applyFunction("one")
res3: Option[Any] = None

scala> applyFunction(1, 1.1, 9L)
res10: Option[Any] = Some(11.1)

这看起来非常不安全,必须有更好的方法来做到这一点。

我认为磁铁模式应该以更安全的方式处理这个问题。