代码之家  ›  专栏  ›  技术社区  ›  user2609980

将方法添加到List并传递匿名参数

  •  0
  • user2609980  · 技术社区  · 9 年前

    我有以下Scala代码来回答 Functional Programming In Scala :

    object Chapter3 {
    
        sealed trait List[+A]
    
        case object Nil extends List[Nothing]
        case class Cons[+A](head: A, tail: List[A]) extends List[A]
    
        object List {
    
            def apply[A](as: A*): List[A] =
                if (as.isEmpty) Nil
                else Cons(as.head, apply(as.tail: _*))
    
            def dropWhile[A](l: List[A], f: A => Boolean): List[A] = 
                l match {
                    case Nil => sys.error("cannot drop from empty list")
                    case Cons(h, t) if f(h) => dropWhile(t, f)
                    case _ => l
                }
    
        }
    
        def main(args : Array[String]) {
            def smallerThanThree(i: Int): Boolean = i < 3
            println( List.dropWhile(List(1, 2, 3, 4, 5), smallerThanThree) )
    
            // How can I call this directly on the list with anonymous function like below?
            println( List(1, 2, 3, 4, 5).dropWhile(i => i < 3) )
            // => Should return List(3, 4, 5) or Cons(3, Cons(4, Cons(5, Nil))).
    
        }
    }
    

    我想做的有两方面:

    1. 呼叫 dropWhile 在列表对象上( List(1,2,3,4,5).dropWhile([f: A => Boolean]) )而不是使用 List.dropWhile([List[A]], [f: A => Boolean])
    2. 传递匿名方法( i => i < 3 ),而不是定义函数 smallerThanThree 并通过这个。

    现在这给出了错误:

    错误:值dropWhile不是Main.List[Int]的成员

    匿名函数也不起作用。当我这样做的时候

    println( List.dropWhile(List(1, 2, 3, 4, 5), i => i < 3) )
    

    它给出错误:

    错误:缺少参数类型

    谁能解释一下以上两点是否可以实现,如果可以,如何实现?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Tzach Zohar    9 年前

    让你能够打电话 dropWhile 在的实例上 特质 List ,该特性必须声明此函数。事实上 对象 通过相同的名称包含此函数不会自动将此方法“添加”到特征中。

    您可以轻松地将这样的函数添加到 列表 将特征定义更改为:

     sealed trait List[+A] {
       def dropWhile(f: A => Boolean): List[A] = List.dropWhile(this, f)
     }
    

    然后,您建议的代码按预期工作。

    至于传递匿名函数-在这种情况下,编译器无法推断 Int 类型,因此必须显式编写类型,如下所示:

    println( List.dropWhile(List(1, 2, 3, 4, 5), (i: Int) => i < 3) )