scala/ScalaBook/chapter-03/hylomorphism.scala

def foldL[α,β](f: (α, β) => β)(e: β)(l: List[α]): β = 
  l match {
    case  Nil  => e
    case x::xs => f(x, foldL(f)(e)(xs))
  }

def unfoldLa[α,β](f: β => Option[Tuple2[α,β]])(u: β):List[α] =
  f(u) match {
    case None      => Nil
    case Some((x,v)) => x::(unfoldLa(f)(v))
  }

def unfoldL[α,β](p: β => Boolean)
                (f: β => α)(g: β => β)
                           (b: β):List[α] =
  if (p(b)) 
    Nil
  else 
    (f(b))::(unfoldL(p)(f)(g)(g(b)))

def insert[α](y:α, xs:List[α])
             (implicit orderer: α => Ordered[α]):List[α] =
  xs match {
    case Nil    => List(y)
    case x::xss =>  if (y < x)  
                      y::x::xss
                    else 
                      x::(insert(y,xss))
  }


var L=List(3,9,5,7,4,1,2,6)
def isort[α](l: List[α])
            (implicit orderer: α => Ordered[α]): List[α] = 
   foldL(insert[α])(Nil)(l)
println(isort[Int](L))

def step[α](x: α, y: Option[Tuple2[α,List[α]]])
            (implicit orderer: α => Ordered[α]) : Option[Tuple2[α,List[α]]] =
  y match {
    case None          => Some((x,Nil))
    case Some((z,zs))  => if (x < z) 
                            Some((x,z::zs))
                          else 
                            Some((z,x::zs)) 
  }

def bubble[α](l: List[α])
            (implicit orderer: α => Ordered[α]) : Option[Tuple2[α,List[α]]]  = 
  foldL(step[α])(None)(l)

def bsort[α](l: List[α])
            (implicit orderer: α => Ordered[α]) : List[α] =
  unfoldLa(bubble[α])(l)

println(bsort[Int](L))

def id(n : Int) = n
def pred(n:Int) = if (n==0) 0 else n-1

def fact(n: Int) = foldL((_:Int) * (_:Int))( 1 )( unfoldL( (_:Int) == 0 )( id )( pred )( n ))
println(foldL( (_:Int) * (_:Int) )( 1 )( unfoldL( (_:Int) == 0 )( id )( pred )( n )))
var w5 = 2*3*4*5
println(w5)