• Scala 函数式程序设计原理(5)--Lists


    5.1 More Functions on Lists

    xs.length  The number of elements of xs

    xs.last    The List's last element, exception if xs is empty

    xs.init    A list consisting of all elements of xs except the last one, exception if xs is empty

    xs take n  A list consisting of the first n elements of xs, or xs itself it is shorter than n

    xs drop n  The rest of the collection after taking n elements

    xs(n)    (or, written out, xs apply n). The element of xs at index n.

    Creating new lists:

    xs ++ ys      The list consisting of all elements of xs followed by all elements of ys

    xs.reverse      The list containing the elements of xs in reversed order

    xs updated (n, x)  The list containing the same elements as xs, except at index n where it contains x.

    Finding elements:

    xs indexOf x    The index of the first element in xs equal to x, or -1 if x does not appear in xs

    xs contains x    same as xs indexOf x >= 0

    5.2 Pairs and Tuples

    A tuple type (t1, ..., tn) is an abbreviation of the parameterized type scala.Tuplen[t1, ..., tn]

    A tuple expression (e1, ..., en) is equivalent to the function application scala.Tuplen(e1, ..., en)

    5.3 Implicit Parameters

    scala.math.Ordering[T] : a class in the standard library that represents orderings.

    Rules for Implicit Parameters:

    Say, a function takes an implicit parameter of type T.

    The compiler will search an implicit definition that

    • is marked implicit
    • has a type compatible with T
    • is visible at the point of the function call, or is defined in a companion object associated with T.

    5.4 Higher-Order List Functions

    Map:

    This scheme can be generalized to the method map of the List class.

    A simple way to define map is as follows:

    abstract class List[T] { ...
      def map[U](f: T => U): List[U] = this match {
        case Nil    => this
        case x :: xs  => f(x) :: xs.map(f)
      }
    }

    Filter:

    This pattern is generalized by the method filter of the List class:

    abstract class List[T] {
      ...
      def filter(p: T => Boolean): List[T] = this match {
        case Nil    => this
        case x :: xs  => if(p(x)) x :: xs.filter(p) else xs.filter(p)
      }
    }

     Using filter, posElems can be writtern more concisely.

    def posElems(xs: List[Int]): List[Int] =
      xs filter (x => x > 0)

     other higher order functions:

    object listfun {
      val nums = List(2, -4, 5, 7, 1)                 //> nums  : List[Int] = List(2, -4, 5, 7, 1)
      val fruits = List("apple", "pineapple", "orange", "banana")
                                                      //> fruits  : List[String] = List(apple, pineapple, orange, banana)
      
      nums filter (x => x > 0)                        //> res0: List[Int] = List(2, 5, 7, 1)
    	nums filterNot (x => x > 0)               //> res1: List[Int] = List(-4)
    	nums partition (x => x > 0)               //> res2: (List[Int], List[Int]) = (List(2, 5, 7, 1),List(-4))
    	nums takeWhile (x => x > 0)               //> res3: List[Int] = List(2)
    	nums dropWhile (x => x > 0)               //> res4: List[Int] = List(-4, 5, 7, 1)
    	nums span (x => x > 0)                    //> res5: (List[Int], List[Int]) = (List(2),List(-4, 5, 7, 1))
    
    }
    

    5.5 Reduction of Lists

    reduceLeft:

    def sum(xs: List[Int])    = (0::xs) reduceLeft (_ + _)
    def product(xs: List[Int])  = (1::xs) reduceRight (_ * _)

    foldLeft:

    foldLeft is like reduceLeft but takes an accumulator, z, as an additional parameter, which is returned when foldLeft is called on an empty list.

    (List(x1, ..., xn) foldLeft z)(op) = (...(z io x1) op ... ) op xn
    

     so sum and product can also be defined as follows:

    def sum(xs: List[Int])     = (xs foldLeft 0) (_ + _)
    def product(xs: List[Int])  = (xs foldLeft 1) (_ * _) 

     implementation:

    abstract class List[T] { ...
      def reduceLeft(op: (T, T) => T):T = this match {
        case Nil => throw new Error("Nil.reduceLeft")
        case x::xs => (xs foldLeft x)(op)
      }

      def foldLeft[U](z: U)(op: (U, T) => U): U = this match {
        case Nil => z
        case x:: xs => (xs foldLeft op(z, x))(op)
      }
    }

    FoldRight and ReduceRight:

    Applications of foldLeft and reduceLeft unfold on trees that lean to the left.

    They have two dual functions, foldRight and reduceRight, which produce trees which lean to the right, i.e.,

    List(x1, ..., x{n-1}, xn) reduceRight op = x1 op ( ... (x{n-1} op xn) ... )
    (List(x1, ..., xn) foldRight acc)(op) = x1 op ( ... (xn op acc) ... )

    implementation:

    def reduceRight(op: (T, T) => T): T = this match {
      case Nil => throw new Error("Nil.reduceRight")
      case x :: Nil => x
      case x :: xs => op(x, xs.reduceRight(op))
    }
    def foldRight[U](z: U)(op: (T, U) => U): U = this match {
      case Nil => z
      case x::xs => op(x, (xs foldRight z)(op))
    }

    Difference between FoldLeft and FoldRight:

    For operators that are associative and commutative, foldLeft and foldRight are equivalent (even though there may be a difference in efficiency)

    But sometimes, only one of the two operators is appropriate.

    implemention of mapFun and lengthFun using foldRight:

    	def mapFun[T, U] (xs: List[T], f: T=> U): List[U] = (xs foldRight List[U]())(f(_) :: _)
                                                      //> mapFun: [T, U](xs: List[T], f: T => U)List[U]
    	mapFun[Int, Int](nums, x => x + 1)        //> res7: List[Int] = List(3, -3, 6, 8, 2)
    	
    	def lengthFun[T](xs: List[T]): Int = (xs foldRight 0) ((_,acc) => acc+1)
                                                      //> lengthFun: [T](xs: List[T])Int
    	lengthFun(nums)                           //> res8: Int = 5
    

    5.6 Reasoning About Concat

    Structual induction:

    To prove a property P(xs) for all lists xs,

    • show that P(Nil) holds (base case),
    • for a list xs and some element x, show the induction step:  if P(xs) holds, then P(x::xs) also holds.
  • 相关阅读:
    hdu 思维风暴
    HDU 4183Pahom on Water(网络流之最大流)
    现在仍在工作的12名最“屌”的程序猿
    安卓ContentObserver模式获取短信用正则自己主动填充验证码
    Android插件实例——360 DroidPlugin具体解释
    mysql---union的使用方法
    SICP 习题 (2.11)解题总结:区间乘法的优化
    jQuery中的ajax
    Ajax的简单总结
    jQuery插件开发
  • 原文地址:https://www.cnblogs.com/PaulingZhou/p/6900143.html
Copyright © 2020-2023  润新知