【问题标题】:How to deal with List of currying function in Scala如何处理Scala中的currying函数列表
【发布时间】:2017-03-26 06:38:22
【问题描述】:

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

  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 & 3,我得到一个编译错误“类型不匹配,预期:String with Int with Double,实际:Int”。如果我确定此处的类型,如何强制编译器避免在此处进行类型检查。

【问题讨论】:

  • 如果你必须检查循环中的哪个函数,那么循环是没有意义的。

标签: scala currying seq


【解决方案1】:

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

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

如果你只是像 tupes 一样写的话......

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    相关资源
    最近更新 更多