如何处理Scala中的currying函数列表

时间:2017-03-26 06:38:22

标签: scala currying seq

在下面的Scala代码中,我有一系列具有不同签名的currying函数。我想迭代它们并调用。

  def intCheck(b: Int)(a: Int) = a == b
  def stringCheck(b: String)(a: String) = a == b
  def doubleCheck(b: Double)(a: Double) = a == b

  val list = Seq(intCheck(1) _, stringCheck("a") _, doubleCheck(2.3) _)

  for (f <- list) {
    //if f is 1st function
    f(2)  // LINE 1
    //if f is 2nd function
    f("a") // LINE 2
    //if f is 3rd function
    f(2.0) // LINE 3
  }

但对于LINE 1,2&amp; 3我收到编译错误&#34;类型不匹配,期望:带有双精度的Int的字符串,实际:Int&#34;。如果我确定这里的类型,我如何强制执行编译器以避免类型检查。

1 个答案:

答案 0 :(得分:0)

我认为这是一种方式......

sealed abstract class AnyChecker(val a:Any,val b:Any) {
    def eval = a==b
}
class IntChecker(override val a:Int,override val  b:Int) extends AnyChecker(a,b)
class DoubleChecker(override val a:Double,override val b:Double) extends AnyChecker(a,b)
class StringChecker(override val a:String,override val b:String) extends AnyChecker(a,b)
object IntChecker {
    def apply(a:Int,b:Int) = new IntChecker(a,b)
    def unapply(intChecker: IntChecker) = Some(intChecker.a,intChecker.b)
}
object DoubleChecker {
    def apply(a:Double,b:Double) = new DoubleChecker(a,b)
    def unapply(doubleChecker: DoubleChecker) = Some(doubleChecker.a,doubleChecker.b)
}
object StringChecker {
    def apply(a:String,b:String) = new StringChecker(a,b)
    def unapply(stringChecker: StringChecker) = Some(stringChecker.a,stringChecker.b)
}
val list = List(IntChecker(1,3), StringChecker("a","a"), DoubleChecker(2.3,3.1), StringChecker("a","b"), StringChecker("a","c"), StringChecker("x","x"))
for (f <- list) {
    f match {
        case a:IntChecker => println(s"a:${a.a}, b:${a.b}, ${a.eval}")
        case a:DoubleChecker => println(s"a:${a.a}, b:${a.b}, ${a.eval}")
        case StringChecker("a","a") => println("equals")
        case StringChecker("a","b") => println("not equals")
        case StringChecker("a",b) => println( StringChecker("a",b).eval)
        case StringChecker(a,b) => println(StringChecker(a,b).eval)
    }
}

请检查this,我相信这会对您有所帮助。 http://bplawler.tumblr.com/post/7493366722/scala-programming-unapply-and-case-classes

另外,另一种简单的方法是仅使用AnyChcker ....

class AnyChecker[T](val a: T, val b: T) {
    def eval = a == b

    override def toString = s"Checker($a,$b)"
}
object AnyChecker {
    def apply[T](a: T, b: T) = new AnyChecker(a, b)

    def unapply[T](doubleChecker: AnyChecker[T]) = Some(doubleChecker.a, doubleChecker.b)
}
val list2 = List(AnyChecker(1, 3), AnyChecker("a", "a"), AnyChecker(2.3, 3.1), AnyChecker("a", "b"), AnyChecker("a", "c"), AnyChecker("x", "x"))
for (checker <- list2) {
    checker match {
        case AnyChecker(1, 3) => println("ints")
        case AnyChecker(2.3, 3.1) => println("doubles")
        case AnyChecker("a","a") => println("double a")
        case checker1: AnyChecker[Any] =>println(checker1)
    }
}

如果你只是像画笔一样写作......

val list3 = List((1, "1"), ("a", "a"), (2.3, 3.1), ("a", "b"), ("a", "c"), ("x", "x")).map(element=>AnyChecker(element._1,element._2))

for (checker <- list3) {
    checker match {
        case AnyChecker(1, 3) => println("ints")
        case AnyChecker(2.3, 3.1) => println("doubles")
        case AnyChecker("a","a") => println("double a")
        case checker1: AnyChecker[Any] =>println(checker1.eval)
    }
}
相关问题