Scalaのお勉強2

昨日と同じく
book.impress.co.jp
に取り組んだ。

今日は第3章。

object Main3{
  private def tail[A](list:List[A]):List[A]={
    list match{
      case Nil=>Nil
      case x::xs=>xs
    }
  }
  private def setHead[A](head:A,list:List[A]):List[A]=head::tail(list)
  @annotation.tailrec
  private def drop[A](l:List[A],n:Int):List[A]=if(n==0)l else drop(tail(l),n-1)
  @annotation.tailrec
  private def dropWhile[A](l:List[A])(f:A => Boolean):List[A]={
    l match{
      case Nil=>Nil
      case x::xs => if(f(x)) dropWhile(xs)(f) else x::xs
    }
  }
  private def init[A](l:List[A]):List[A]={
    l match{
      case Nil=>Nil
      case x::Nil=>Nil
      case x::xs=>x::init(xs)
    }
  }
  private def foldRight[A,B](as:List[A],z:B)(f:(A,B)=>B):B ={
    as match{
      case Nil=>z
      case x::xs => f(x,foldRight(xs,z)(f))
    }
  }
  private def length[A](as:List[A]):Int=foldRight(as,0)((_,b)=>b+1)
  @annotation.tailrec
  private def foldLeft[A,B](as:List[A],z:B)(f:(B,A)=>B):B={
    as match{
      case Nil=>z
      case x::xs=>foldLeft(xs,f(z,x))(f)
    }
  }
  
  private def sum(ints:List[Int])=foldLeft(ints,0)(_+_)
  private def product(ints:List[Int])=foldLeft(ints,1)(_*_)
  private def length2[A](as:List[A]):Int=foldLeft(as,0)((b,_)=>b+1)
  private def reverse[A](as:List[A])=foldLeft(as,List[A]())((bs,a)=>a::bs)
  private def append[A](a1:List[A],a2:List[A]):List[A]=foldRight(a1,a2)(_::_)
  private def plus1(ints:List[Int]):List[Int]=foldRight(ints,List[Int]())((a,bs)=>(a+1)::bs)
  private def ds2ss(doubles:List[Double]):List[String]=foldRight(doubles,List[String]())((a,bs)=>a.toString::bs)
  private def map[A,B](as:List[A])(f:A=>B):List[B]=foldRight(as,List[B]())((a,bs)=>f(a)::bs)
  private def filter[A](as:List[A])(f:A=>Boolean):List[A]=foldRight(as,List[A]())((a,bs)=>if (f(a)) a::bs else bs)
  private def flatMap[A,B](as:List[A])(f:A=>List[B]):List[B]=foldRight(map(as)(f),List[B]())(append(_,_))
  private def filter2[A](as:List[A])(f:A=>Boolean):List[A]=flatMap(as)(a=>if (f(a)) List(a) else List[A]())
  private def pluslists(a1:List[Int],a2:List[Int]):List[Int]={
    (a1,a2) match{
      case (_,Nil)=>Nil
      case (Nil,_)=>Nil
      case ((x::xs),(y::ys))=>(x+y)::pluslists(xs,ys)
    }
  }
  private def zipWith[A,B,C](as:List[A],bs:List[B])(f:(A,B)=>C):List[C]={
    (as,bs) match{
      case (_,Nil)=>Nil
      case (Nil,_)=>Nil
      case ((x::xs),(y::ys))=>(f(x,y))::zipWith(xs,ys)(f)
    }
  }

  
  sealed trait Tree[+A]
  case class Leaf[A](value:A) extends Tree[A]
  case class Branch[A](left:Tree[A],right:Tree[A]) extends Tree[A]

  private def size[A](tree:Tree[A]):Int={
    tree match{
      case Leaf(_)=>1
      case Branch(left,right)=>size(left)+size(right)+1
    }
  }
  private def maximum(tree:Tree[Int]):Int={
    tree match{
      case Leaf(x)=>x
      case Branch(left,right)=>maximum(left) max maximum(right)
    }
  }

  private def depth[A](tree:Tree[A]):Int={
    tree match{
      case Leaf(x)=>1
      case Branch(left,right)=>(depth(left) max depth(right))+1
    }
  }
  private def map[A,B](tree:Tree[A])(f:A=>B):Tree[B]={
    tree match{
      case Leaf(x)=>Leaf(f(x))
      case Branch(left,right)=>Branch(map(left)(f),map(right)(f))
    }
  }
  private def fold[A,B](tree:Tree[A])(l:A=>B)(b:(B,B)=>B):B={
    tree match{
      case Leaf(x)=>l(x)
      case Branch(left,right)=>b(fold(left)(l)(b),fold(right)(l)(b))
    }
  }

    
  
  def main(args:Array[String]){
    println(tail(List(1,2,3,4,5)))
    println(tail(List(1)))
    println(tail(Nil))
    println(setHead(100,List(1,2,3,4,5)))
    println(drop(List(1,2,3,4,5),3))
    println(dropWhile(List[Int](1,2,3,4,5,6))(3 >=))
    println(init(List(1,2,3,4,5,6,7,8)))
    println(length(List(1,2,3,4,5,6,7)))
    println(sum(List(1,2,3)))
    println(product(List(1,2,3)))
    println(length2(List(1,2,3)))
    println(reverse(List(3,2,1)))
    println(append(List(1,2,3),List(4,5,6)))
    println(plus1(List(0,1,2)))
    println(ds2ss(List(0.0,1,1,2.2)))
    println(map(List(0,1,2))(1+_))
    println(filter(List(0,1,2))(0<_))
    println(flatMap(List(1,2,3))(i=>List(i,i)))
    println(zipWith(List(1,2,3),List(4,5,6))(_+_))
    val branch=Branch(Branch(Leaf("a"),Leaf("b")),Branch(Leaf("c"),Leaf("d")))
    println(size(branch))
    println(depth(branch))
    println(map(branch)(_*3))
  }

}

間違ってConsじゃなくてListでやっちゃった。