SlideShare une entreprise Scribd logo
1  sur  112
Télécharger pour lire hors ligne
Functional Scaλa

                                       … in Practice

          20.10.2010
          Java User Group Frankfurt / Main
          Mario Gleichmann




Mario Gleichmann                                       JUG Frankfurt / Main
Introduction

               Mario Gleichmann

                   site:   www.mg-informatik.de


                   blog:   'brain driven development'
                           gleichmann.wordpress.com


                   mail:   mario.gleichmann@mg-informatik.de



Mario Gleichmann                      2                        JUG Frankfurt / Main
Summary




Mario Gleichmann      3      JUG Frankfurt / Main
What is Functional Programming ?


                             Functional Style


                        val sum = fold( 1 to 10, add )




                               Expression based

                   Computation method is function application

Mario Gleichmann                      4   fcn                   JUG Frankfurt / Main
What makes a Function ?


                                 Function Types



                    val add = ( x :Int, y :Int ) => x + y



                   Type of add : ( Int , Int ) => Int




Mario Gleichmann                           5   Obj          JUG Frankfurt / Main
Closures


                                      'closing over'
                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit




                                    'Closed term'




Mario Gleichmann                              6   appl          JUG Frankfurt / Main
Algebraic Datatypes


                               Example - Tree

         data Tree = Empty | Leaf Int | Node Int Tree Tree


         abstract case class Tree()
         case object Empty extends Tree
         case class Leaf( value: Int ) extends Tree
         case class Node( value: Int, left :Tree, right: Tree ) extends Tree




Mario Gleichmann                          7   insrt                        JUG Frankfurt / Main
Pattern Matching



       val depth :Tree => Int = _ match {

              case Empty                    => 0

              case Leaf( _ )                => 1

              case Node( _, left, right )   => 1 + max( depth( left ), depth( right ) )
       }




Mario Gleichmann                              8   Prt isb                       JUG Frankfurt / Main
Partial Functions


         type =>?[-A, +B] = PartialFunction[A, B]


         val publisherRegionDE : Isbn =>? String = {

                   case Isbn( 3, pubNr, _ )   => "D" + ( pubNr.toString charAt 0 )
         }

         …

         publisherRegionDE.isDefinedAt( Isbn( 0, 677873, 8823 ) ) )

         >> false



Mario Gleichmann                               9   chn                         JUG Frankfurt / Main
Comprehensions


      val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x

      ...

      val prime = ( n :Int ) => factors( n ).toList == List( 1, n )

      …

      val primes = (n :Int) => for( x <- (1 to n) if prime( x ) ) yield x




Mario Gleichmann                        10   Hgh rdr Fcn                 JUG Frankfurt / Main
Higher Order Functions




         val filter = ( predicate: Int => Boolean , xs :List[Int] ) => {

                   for( x <- xs; if predicate( x ) ) yield x
         }




Mario Gleichmann                           11   Fcn Tp              JUG Frankfurt / Main
Lambda Expressions



               filter( num => num % 2 == 0, List( 1, 2, 3, 4, 5, 6 ) )

               …


               filter( _ > 0, List( -1, 5, 0, -3, 7 ) )




Mario Gleichmann                             12   fst arg                JUG Frankfurt / Main
Partial Application




Mario Gleichmann           13            JUG Frankfurt / Main
Partial Application




                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )

                   Type of isPrime: Int => Boolean




Mario Gleichmann                              14   def prms wthn           JUG Frankfurt / Main
Partial Application


                                         Delegation



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs )


             Type of filter: ( Int => Boolean, List[Int] ) => List[Int]



Mario Gleichmann                              15   fxd var                   JUG Frankfurt / Main
Partial Application


                                         Delegation



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs )

                                                                fixed    variable




Mario Gleichmann                              16   appl nappl                JUG Frankfurt / Main
Partial Application


                                     New from Old ...



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = filter( isPrime, _ :List[Int] )


                                            applied         unapplied




Mario Gleichmann                              17   Fcn Tp                  JUG Frankfurt / Main
Partial Application


                                     New from Old ...



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = filter( isPrime, _ :List[Int] )

              Type of primesWithin: List[Int] => List[Int]



Mario Gleichmann                              18   Crrng                   JUG Frankfurt / Main
Currying




Mario Gleichmann      19      JUG Frankfurt / Main
Currying




                   val filter =   ( pred: Int => Boolean , xs :List[Int] ) => {
                         for( x <- xs; if pred( x ) ) yield x
                   }

                   Type of filter:   ( Int => Boolean , List[Int] ) => List[Int]


Mario Gleichmann                                20   Crrd fcn                 JUG Frankfurt / Main
Currying


                    'Higher Order Lambda Closures' ...


         val filter =    ( pred: Int => Boolean ) => ( xs :List[Int] ) => {
                   for( x <- xs; if pred( x ) ) yield x
         }




Mario Gleichmann                           21   Crrd fcn Tp            JUG Frankfurt / Main
Currying


                    'Higher Order Lambda Closures' ...


         val filter =    ( pred: Int => Boolean ) => ( xs :List[Int] ) => {
                   for( x <- xs; if pred( x ) ) yield x
         }

      Type of filter:       ( Int => Boolean ) => ( List[Int] ) => List[Int]


Mario Gleichmann                           22   sngl arg               JUG Frankfurt / Main
Currying


                    'Higher Order Lambda Closures' ...


         val filter =    ( pred: Int => Boolean ) => ( xs :List[Int] ) => {
                   for( x <- xs; if pred( x ) ) yield x
         }

      Type of filter:       ( Int => Boolean ) => ( List[Int] ) => List[Int]
                                                Curried Function
                                                    Curried Function


Mario Gleichmann                           23   sngl
                                                xpln arg               JUG Frankfurt / Main
Currying


                       'Higher Order Lambda Closures' ...


         val filter =       ( pred: Int => Boolean ) => ( xs :List[Int] ) => {
                      for( x <- xs; if pred( x ) ) yield x
         }

      Type of filter:           ( Int => Boolean ) => ( List[Int] ) => List[Int]
                                  ... accepting one            ... resulting in another
                   A function
                                    (Function) Arg                     function

Mario Gleichmann                               24   lmbd xpr                         JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]


                                      ... is defined as a Lambda expession


Mario Gleichmann                         25   cls ovr                   JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]

                                    ... closes over to Arguments (Scope)
                                         of surrounding Function 'filter'

Mario Gleichmann                         26   Smp prms wthn             JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )




Mario Gleichmann                           27   Fcn Tp                JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )

           Type of primesWithin: List[Int] => List[Int]



Mario Gleichmann                           28   appl                  JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )

           ...
           primesWithin( List( 3, 4, 5, 6, 7 ) )              >> List( 3, 5, 7 )


Mario Gleichmann                           29   Smp rc mgmt                  JUG Frankfurt / Main
Example 2 – Ressource Management
     val initQuery =
      (dataSource :DataSource) => (query :String) => ( extractor :ResultSet => Unit ) => {

          try{
            val conn = dataSource.getConnection
            val stmt = conn.createStatement
            val resultSet = stmt.executeQuery( query )
            extractor( resultSet )
          }
          finally{
            try{
              if( conn != null ) conn.close
            }
            finally{
              if( stmt != null ) stmt.close
            }
          }
      }


Mario Gleichmann                                30   appl                          JUG Frankfurt / Main
Example 2 – Ressource Management
     val dataSource :DataSource = ...;

     ...
     val query = initQuery( dataSource )

     …

     query( "select * from User where age > 18" ) { result :ResultSet =>
           while( result.next ) { .... }
       }

     …

     query( "select * from Account where balance < 1000" ) { result :ResultSet =>
           while( result.next ) { .... }
       }



Mario Gleichmann                           31   smmy                       JUG Frankfurt / Main
Combinators




Mario Gleichmann       32        JUG Frankfurt / Main
Combinators


            val power : Int => Int => Int =

                   ( base :Int ) => ( exp :Int ) =>

                    if( exp == 1 ) base else base * power( base )( exp - 1 )


            ...

            val square = power( _ :Int )( 2 )



Mario Gleichmann                              33                        JUG Frankfurt / Main
Combinators


            val power : Int => Int => Int =

                   ( base :Int ) => ( exp :Int ) =>

                    if( exp == 1 ) base else base * power( base )( exp - 1 )


            ...

            val square = power( _ :Int )( 2 )

            Type of square : Int => Int

Mario Gleichmann                              34                        JUG Frankfurt / Main
Combinators


            val power : Int => Int => Int =

                   ( base :Int ) => ( exp :Int ) =>

                    if( exp == 1 ) base else base * power( base )( exp - 1 )


            ...

            val square = power( _ :Int )( 2 )

                              Partial Application 'in the middle'

Mario Gleichmann                               35                       JUG Frankfurt / Main
Combinators


     def flipArgs [A, B, C] ( f: A => B => C ) : B => A => C =

           ( x: B ) => ( y: A ) => f (y) (x)



                     Transforms to another Function,
                   expecting arguments in reversed order




Mario Gleichmann                            36              JUG Frankfurt / Main
Combinators


     def flipArgs [A, B, C] ( f: A => B => C ) : B => A => C =

           ( x: B ) => ( y: A ) => f (y) (x)


     …

     val square = flipArgs( power )( 2 )


                             … now just exploit Currying



Mario Gleichmann                       37                   JUG Frankfurt / Main
Combinators

                                 Function Composition


                   f :: B => C

                   g :: A => B

                   x   ∈   A


                   ( f o g )( x ) = f ( g ( x ) )
                   ( f o g ) :: A => C

Mario Gleichmann                          38            JUG Frankfurt / Main
Combinators : Function Composition

                   def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C =
                    ( x :A ) => f( g( x ) )

                   ...
                   val mult = ( x :Int ) => ( y: Int ) => x * y
                   val add = ( x :Int ) => ( y: Int ) => x + y

                   ...
                   val doubleSucc = o ( mult(2) ) ( add(1) )

                   Type of doubleSucc : Int => Int



Mario Gleichmann                                  39                      JUG Frankfurt / Main
Combinators : Function Composition

                   def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C =
                    ( x :A ) => f( g( x ) )

                   ...
                   val mult = ( x :Int ) => ( y: Int ) => x * y
                   val add = ( x :Int ) => ( y: Int ) => x + y

                   ...
                   val doubleSucc = o ( mult(2) ) ( add(1) )

                   doubleSucc( 7 )

                   >> 16

Mario Gleichmann                                  40                      JUG Frankfurt / Main
Combinators : Function Composition

                   def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C =
                    ( x :A ) => f( g( x ) )

                   ...
                   val mult = ( x :Int ) => ( y: Int ) => x * y
                   val add = ( x :Int ) => ( y: Int ) => x + y

                   ...
                   val doubleSucc = o ( mult(2) ) ( add(1) )

                   doubleSucc( 7 )
                                              Postfix ...
                   >> 16

Mario Gleichmann                                  41                      JUG Frankfurt / Main
Combinators : Function Composition

         class RichFunc [B, C] ( f: B => C ) {
                   def o[A] ( g: A => B ) = (x :A) => f( g( x ) )
         }

         implicit def toRichFunc[B,C]( f: B => C ) = new RichFunc( f )



         ...
         val doubleSucc = mult(2) o add(1)

         doubleSucc( 7 )                     Infix !!!

         >> 16

Mario Gleichmann                               42                   JUG Frankfurt / Main
Combinators : Function Composition

         class RichFunc [B, C] ( f: B => C ) {
                   def o[A] ( g: A => B ) = (x :A) => f( g( x ) )
         }

         implicit def toRichFunc[B,C]( f: B => C ) = new RichFunc( f )



         ...
         val doubleSucc = mult(2) o add(1)

         doubleSucc( 7 )               'Point free style' of function definition

         >> 16

Mario Gleichmann                                43                                 JUG Frankfurt / Main
Example: Word Counter


     Count all even words within a sentence:


     “Hello World“                             → 0

     “The fox jumps over the lazy dog“         → 2

     "This sentence contains five even words" → 5




Mario Gleichmann                  44                 JUG Frankfurt / Main
Example: Word Counter


     Count all even words within a sentence:


     “Hello World“                              → 0

     “The fox jumps over the lazy dog“          → 2

     "This sentence contains five even words" → 5


     Basic Functions:

     parse Words → Word to length → filter even → count


Mario Gleichmann                   45                     JUG Frankfurt / Main
Example: Word Counter


                            Basic Functions

     val words = ( sentence : String ) => sentence.split( " " ).toList

     val length = ( ws :List[String] ) => for( w <- ws ) yield w.length

     val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ...

     val even = ( i :Int ) => i % 2 == 0

     val size = ( xs :List[ _ ] ) => xs.size




Mario Gleichmann                       46                               JUG Frankfurt / Main
Example: Word Counter

     val words = ( sentence : String ) => sentence.split( " " ).toList

     val length = ( ws :List[String] ) => for( w <- ws ) yield w.length

     val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ...

     val even = ( i :Int ) => i % 2 == 0

     val size = ( xs :List[ _ ] ) => xs.size


     val evenWordCount = size o filter( even ) o length o words

     Type of evenWordCount : String => Int


Mario Gleichmann                       47                               JUG Frankfurt / Main
Example: Word Counter

     val words = ( sentence : String ) => sentence.split( " " ).toList

     val length = ( ws :List[String] ) => for( w <- ws ) yield w.length

     val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ...

     val even = ( i :Int ) => i % 2 == 0

     val size = ( xs :List[ _ ] ) => xs.size


     val evenWordCount = size o filter( even ) o length o words
                               vs.
     val evenWordCount = (sentence :String ) =>
       size ( filter( even ) ( length( words( sentence ) ) ) )
Mario Gleichmann                       48                               JUG Frankfurt / Main
Example: Word Counter

     val words = ( sentence : String ) => sentence.split( " " ).toList

     val length = ( ws :List[String] ) => for( w <- ws ) yield w.length

     val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ...

     val even = ( i :Int ) => i % 2 == 0

     val size = ( xs :List[ _ ] ) => xs.size


     val evenWordCount = size o filter( even ) o length o words

     evenWordCount( "this sentence contains five even words" )
     >> 5
Mario Gleichmann                       49                               JUG Frankfurt / Main
Fundamental Functions




Mario Gleichmann            50             JUG Frankfurt / Main
Fundamental Functions


                   def sum ( list : List[Int] ) : Int = list match {

                       case Nil       => 0

                       case x :: xs => x + sum( xs )
                   }




Mario Gleichmann                               51                      JUG Frankfurt / Main
Fundamental Functions


                   def product ( list : List[Int] ) : Int = list match {

                       case Nil       => 1

                       case x :: xs => x * product( xs )
                   }




Mario Gleichmann                               52                          JUG Frankfurt / Main
Fundamental Functions


                   def allTrue ( ys : List[Boolean] ) : Boolean = ys match {

                        case Nil      => true

                        case x :: xs => x and allTrue( xs )
                    }




Mario Gleichmann                            53                          JUG Frankfurt / Main
Fundamental Functions : reduce


                   def reduce ( list : List[ T ] ) : R = list match {

                        case Nil     =>   ?
                        case x :: xs => x     ʘ    reduce( xs )
                    }




Mario Gleichmann                              54                        JUG Frankfurt / Main
Fundamental Functions : reduce


                   def reduce ( list : List[ T ] ) : R = list match {

                        case Nil     =>   ?           'unit'


                        case x :: xs => x     ʘ    reduce( xs )
                    }
                                      'subsuming operation'




Mario Gleichmann                              55                        JUG Frankfurt / Main
Fundamental Functions : reduce


          def reduce[T,R] ( fun : T => R => R ) ( unit : R ) ( list : List[T] ) : R =
             list match {

                   case Nil      => unit

                   case x :: xs => fun ( x ) ( reduce( fun )( unit )( xs ) )
             }




Mario Gleichmann                                56                              JUG Frankfurt / Main
Fundamental Functions : reduce


          def reduce[T,R] ( fun : T => R => R ) ( unit : R ) ( list : List[T] ) : R =
             list match {

                   case Nil      => unit

                   case x :: xs => fun ( x ) ( reduce( fun )( unit )( xs ) )
             }


               reduce ʘ unit t1 :: t2 :: t3 :: t4 :: Nil
                =>
                 t1 ʘ ( t2 ʘ ( t3 ʘ ( t4 ʘ unit ) ) )
Mario Gleichmann                                57                              JUG Frankfurt / Main
Fundamental Functions : reduce


            val add = (x : Int) => (y : Int) => x + y

            val mult = (x : Int) => (y : Int) => x * y

            ...
            val sum = reduce ( add ) ( 0 ) _

            val product = reduce ( mult ) ( 1 ) _

            ...
            sum( List( 1, 2, 3, 4 ) )            >> 10

            product( List( 1, 2, 3, 4 ) )        >> 24

Mario Gleichmann                            58           JUG Frankfurt / Main
Fundamental Functions : reduce

          val or = ( x :Boolean ) => ( y :Boolean ) => x || y
          val and = ( x :Boolean ) => ( y :Boolean ) => x && y
          val not = ( x :Boolean ) => !x

          ...
          val existOneTrue = reduce ( or ) ( false ) _
          val allFalse = not o reduce ( or ) ( false ) _
          val allTrue = reduce ( and ) ( true ) _

         ...
          allTrue( List( 1 < 2, 3 == 3, 1 + 1 == 2 ) )          >> true


Mario Gleichmann                      59                              JUG Frankfurt / Main
Example: List concatenation


          def append[T] (x:T) (xs:List[ _ ]) = x :: xs

          val listConcat = reduce ( append ) _


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )
          >> List( 8, 9, 1, 2, 3, 4 )

          listConcat ( List( true, true, false ) ) ( List( true, false ) ) )
          >> List( true, false, true, true, false )



Mario Gleichmann                          60                             JUG Frankfurt / Main
Example: List concatenation


          def append[T] (x:T) (xs:List[ _ ]) = x :: xs

          val listConcat = reduce ( append ) _


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )
          >> List( 8, 9, 1, 2, 3, 4 )          'unit'

          listConcat ( List( true, true, false ) ) ( List( true, false ) ) )
          >> List( true, false, true, true, false )



Mario Gleichmann                          61                             JUG Frankfurt / Main
Example: List concatenation


          def append[T] (x:T) (xs:List[ _ ]) = x :: xs

          val listConcat = flipArgs( reduce ( append ) _ )


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )
          >> List( 1, 2, 3, 4, 8, 9 )

          listConcat ( List( true, true, false ) ) ( List( true, false ) ) )
          >> List( true, true, false, true, false )



Mario Gleichmann                          62                             JUG Frankfurt / Main
Example: List concatenation


          def append[T] (x:T) (xs:List[ _ ]) = x :: xs

          val listConcat = flipArgs( reduce ( append ) _ )


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )
          >> List( 1, 2, 3, 4, 8, 9 )                   'unit'

          listConcat ( List( true, true, false ) ) ( List( true, false ) ) )
          >> List( true, true, false, true, false )



Mario Gleichmann                          63                             JUG Frankfurt / Main
Example: List concatenation




                                                                 !
          def append[T] (x:T) (xs:List[ _ ]) = x :: xs

          val listConcat = flipArgs( reduce ( append ) _ )


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )

          Type of result: List[Any]




Mario Gleichmann                          64                     JUG Frankfurt / Main
Example: List concatenation


          def append[T] (x:T) (xs:List[ T ]) = x :: xs

          def listConcat[A] ( a: List[A]) ( b: List[A] ) : List[A] =
              reduce[ A, List[A] ] ( ( append[A] ) _ ) (b) (a)


          listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) )

          Type of result: List[Int]




Mario Gleichmann                          65                           JUG Frankfurt / Main
More
                   Fundamental Functions



Mario Gleichmann            66             JUG Frankfurt / Main
Fundamental Functions

          val doubleAll : List[Int] => List[Int] =         _ match {
                   case Nil       => Nil
                   case y :: ys   => y * 2 :: doubleAll( ys )
          }



          doubleAll( List( 1, 2, 3, 4 ) )

          >> List( 2, 4, 6, 8 )




Mario Gleichmann                           67                          JUG Frankfurt / Main
Fundamental Functions

          val toLength : List[String] => List[Int] = _ match {

                   case Nil       => Nil

                   case y :: ys   => y.length :: toLength( ys )
          }


          toLength( List( "a", "ab", "abc", "abcde" ) ) )

          >> List( 1, 2, 3, 5 )




Mario Gleichmann                           68                     JUG Frankfurt / Main
Fundamental Functions : map

          val map : List[T] => List[R] = _ match {

                   case Nil       => Nil

                   case y :: ys   => f?( y ) :: map( ys )
          }




Mario Gleichmann                           69               JUG Frankfurt / Main
Fundamental Functions : map

          def map[T, R] ( f: T => R ) : List[T] => List[R] =

                   ( xs : List[T] ) => xs match {

                       case Nil       => Nil

                       case y :: ys   => f( y ) :: map( f )( ys )
                   }




Mario Gleichmann                               70                   JUG Frankfurt / Main
Fundamental Functions : map

          def map[T, R] ( f: T => R ) : List[T] => List[R] =

                   ( xs : List[T] ) => xs match {

                       case Nil       => Nil

                       case y :: ys   => f( y ) :: map( f )( ys )
                   }

                   Accepting a function to          Resulting in another function,
                   apply on every element           accepting the List of elements




Mario Gleichmann                               71                                JUG Frankfurt / Main
Fundamental Functions : map

          def map[T, R] ( f: T => R ) : List[T] => List[R] = ...


          ...
          val mult = (x : Int) => (y : Int) => x * y

          val doubleAll = map( mult( 2 ) )


          ...
          val toLength = map( ( s :String ) => s.length )




Mario Gleichmann                        72                         JUG Frankfurt / Main
Fundamental Functions : map

          val add = (x : Int) => (y : Int) => x + y

          val sum = reduce ( add ) ( 0 ) _

          val sumMatrix = sum o map( sum )



          Type of sum :            List[Int] => Int

          Type of map( sum ) : List[List[Int]] => List[Int]

          Type of sumMatrix :      List[List[Int]] => Int


Mario Gleichmann                       73                     JUG Frankfurt / Main
Fundamental Functions : map

          val add = (x : Int) => (y : Int) => x + y

          val sum = reduce ( add ) ( 0 ) _

          val sumMatrix = sum o map( sum )


          ...
          val matrix =    List( List( 1, 2, 3 ),
                                List( 4, 5, 6 ),
                                List( 7, 8, 9 ) )

          sumMatrix( matrix )          >> 45


Mario Gleichmann                        74            JUG Frankfurt / Main
map via reduce



          def applyAndPrepend [A, B] ( f: A => B ) =
                   ( a :A ) => ( bs :List[B] ) => f( a ) :: bs



          def map [A, B] ( f: A => B ) : List[A] => List[B] =
                   reduce ( applyAndPrepend( f ) ) ( Nil ) _




Mario Gleichmann                           75                    JUG Frankfurt / Main
map via reduce



          def applyAndPrepend [A, B] ( f: A => B ) =
                   ( a :A ) => ( bs :List[B] ) => f( a ) :: bs



          def map [A, B] ( f: A => B ) : List[A] => List[B] =
                   reduce ( applyAndPrepend( f ) ) ( Nil ) _


                       f ::   f ::   f ::   f ::   Nil

                      X1 :: X2 :: X3 :: X4 :: Nil
Mario Gleichmann                             76                  JUG Frankfurt / Main
filter via reduce


      def filter[T]( pred :T => Boolean ) : List[T] => List[T] =
              reduce ( ( x :T ) => ( acc :List[T] ) =>
                                         if( pred( x ) ) x :: acc else acc )
                     ( Nil )




Mario Gleichmann                         77                            JUG Frankfurt / Main
Type Classes




Mario Gleichmann        78        JUG Frankfurt / Main
Type Classes



                   def sum( xs : List[Int] ) : Int = xs match {

                       case Nil             => 0

                       case head :: tail    => head + sum( tail )
                   }




Mario Gleichmann                            79                      JUG Frankfurt / Main
Type Classes



                   def sum( xs : List[String] ) : String = xs match {

                       case Nil            => ““

                       case head :: tail   => head + sum( tail )
                   }

                                                   Concatenation !




Mario Gleichmann                           80                           JUG Frankfurt / Main
Type Classes



                   def sum[A]( xs : List[A] ) : A = xs match {

                       case Nil            =>   ?
                       case head :: tail   => head ? sum( tail )
                   }




Mario Gleichmann                           81                      JUG Frankfurt / Main
Type Classes



                   def sum[A]( xs : List[A] ) : A = xs match {

                       case Nil            =>   ?        'neutral' element


                       case head :: tail   => head ? sum( tail )
                   }
                                                 element composition




Mario Gleichmann                           82                           JUG Frankfurt / Main
Type Classes


                   trait SemiGroup[S] {

                       def add( x : S, y : S ) : S         element composition
                   }



                   trait Monoid[M] extends SemiGroup[M] {

                       def unit : M         'neutral' element
                   }



Mario Gleichmann                                83                               JUG Frankfurt / Main
Type Classes



         def sum [A] ( xs : List[A], m: Monoid[A] ) : A =

            xs match {

                   case Nil             => m.unit

                   case head :: tail    => m.add( head, sum( tail, m) )

            }




Mario Gleichmann                            84                        JUG Frankfurt / Main
Type Classes



         def sum [A] ( xs : List[A], m: Monoid[A] ) : A =
                                        'type constraint'
            xs match {

                   case Nil             => m.unit

                   case head :: tail    => m.add( head, sum( tail, m) )

            }




Mario Gleichmann                             85                       JUG Frankfurt / Main
Type Classes


              object IntMonoid extends Monoid[Int]{
                   def add(x : Int, y : Int): Int = x + y
                   def unit : Int = 0
              }

              …

              sum( List( 1, 2, 3, 4 ), IntMonoid )




Mario Gleichmann                               86           JUG Frankfurt / Main
Type Classes

         def sum [A] ( xs : List[A] ) ( implicit m: Monoid[A] ) : A = ...

         implicit object IntMonoid extends Monoid[Int]{ … }

         …


         import typeclasses.monoid._
         ...

         sum( List( 1, 2, 3, 4 ) )



Mario Gleichmann                       87                            JUG Frankfurt / Main
Example: Clock-Monoid

      sealed abstract case class ClockHour( hour: Int )
      case object HOUR_0 extends ClockHour( 0 )
      case object HOUR_1 extends ClockHour( 1 )
      ...
      case object HOUR_11 extends ClockHour( 11 )


      …
      implicit object ClockHourMonoid extends Monoid[ClockHour]{

          val hours = Array( HOUR_0, HOUR_1, HOUR_2, ..., HOUR_11 )

          def add(x : ClockHour, y : ClockHour) = hours( ( x.hour + y.hour ) % 12 )

          def unit : ClockHour = HOUR_0
      }


Mario Gleichmann                            88                                JUG Frankfurt / Main
Example: Clock-Monoid

         import typeclasses.monoid.ClockHourMonoid
         ...


         sum( List( HOUR_5, HOUR_3, HOUR_8 ) )


         >> HOUR_4




Mario Gleichmann                 89                  JUG Frankfurt / Main
Example: Contains element ?
     trait Eq[E]{
        def equals( e1 :E, e2 :E ) : Boolean
     }


     def contains [T] ( x :T, xs : List[T] )
                        ( implicit eq :Eq[T] ) : Boolean =
       reduce
           ( ( y :T ) => ( acc :Boolean ) =>
                              if( eq.equals( x, y ) ) true else acc )
           ( false )                       1st Arg: 'reducing' function
                   ( xs )
                                           2nd Arg: 'unit'

                            3rd Arg: List to reduce
Mario Gleichmann                               90                   JUG Frankfurt / Main
Example: Contains element ?
     case class Person( name :String, age :Int )

     implicit object PersonEq extends Eq[Person]{
             def equals( p1 :Person, p2 :Person ) : Boolean =
                (p1.name == p2.name) && (p1.age == p2.age)
     }

     ...
     val persons = List( Person("Hans", 22),
                         Person( "Helga", 32 ),
                         Person( "Hugo", 47 ) )

     contains( Person( "Olga", 22 ), persons )        >> false
     contains( Person( "Helga", 32 ), persons )       >> true
Mario Gleichmann                     91                          JUG Frankfurt / Main
Monads




Mario Gleichmann     92     JUG Frankfurt / Main
Monads

                            A simple Monad: Option

                                    << abstract >>

                                     Option[+A]




                           Some[+A]                  None

                               presence           absence
                   Handling the             or              of something

                            ...as the result of a computation
                              (computational environment)
Mario Gleichmann                                                           JUG Frankfurt / Main
Monads

                            A simple Monad: Option

          class CustomerDAO{

              def findCustomer( custId: Long ) : Option<Customer> = {
                ...
                if( found( customer ) ) Some( customer ) else None
              }
          }




Mario Gleichmann                                                 JUG Frankfurt / Main
Monads

                            A simple Monad: Option

          class CustomerDAO{

              def findCustomer( custId: Long ) : Option<Customer> = {
                ...
                if( found( customer ) ) Some( customer ) else None
              }
          }
                           Explicit Notion, that there may be 'none' result




Mario Gleichmann                                                          JUG Frankfurt / Main
Monads

                               A simple Monad: Option

           val customerHit = customerDAO.findCustomer( 123 );
           ...

           customerHit match {

                   case Some( customer )   => println( customer.name )

                   case None               => println( “not found“ )
           }




Mario Gleichmann                                                       JUG Frankfurt / Main
Monads

                                A simple Monad: Option

           val customerHit = customerDAO.findCustomer( 123 );
           ...

           customerHit match {

                   case Some( customer )       => println( customer.name )

                   case None                   => println( “not found“ )
           }

                     Explicit Handling the absensce of a result
                                Forces 'Awareness'
Mario Gleichmann                                                           JUG Frankfurt / Main
Monads

                               A simple Monad: Option

           val customerHit = customerDAO.findCustomer( 123 );
           ...

           customerHit match {

                   case Some( customer )     => println( customer.name )

                   case None                 => println( “not found“ )
           }


                     ... beside from that ... what's the deal ???

Mario Gleichmann                                                         JUG Frankfurt / Main
Monads

                               A simple Monad: Option

           val customerHit = customerDAO.findCustomer( 123 );
           ...

           customerHit match {

                   case Some( customer )   => println( customer.name )

                   case None               => println( “not found“ )
           }


                   'Protected' Function Composition ...
Mario Gleichmann                                                       JUG Frankfurt / Main
Monads


               val projects =     Map(    "Jan"   ->   "IKT",
                                          "Joe"   ->   "TensE",
                                          "Luca" ->    "InTA" )

                   val customers = Map(   "IKT"   ->   "Hanso GmbH",
                                          "InTA" ->    "RAIA Duo" )

                   val cities =   Map(    "Hanso GmbH" ->         "Stuttgart",
                                          "Mogno"          ->     "Mailand" )




Mario Gleichmann                                                            JUG Frankfurt / Main
Monads


               val projects =       Map(    "Jan"   ->   "IKT",
                                            "Joe"   ->   "TensE",
                                            "Luca" ->    "InTA" )

                   val customers = Map(     "IKT"   ->   "Hanso GmbH",
                                            "InTA" ->    "RAIA Duo" )

                   val cities =     Map(    "Hanso GmbH" ->         "Stuttgart",
                                            "Mogno"          ->     "Mailand" )

                                  Where is Jan ?
                          Jan -> IKT -> Hanso GmbH -> Stuttgart
Mario Gleichmann                                                              JUG Frankfurt / Main
Monads
                                                                      Jav
                   public String whereIs( String name ){




                                                                         a
                       String project = projects.get( name );
                       if( project != null ){
                           String customer = customers.get( project );
                           if( customer != null ){
                               String city = cities.get( customer )
                               if( city != null ) return city;
                                  else return “unknown“;
                           }
                           else return ''unknown'';
                       }
                       else return ''unknown'';
                   }


Mario Gleichmann                                                             JUG Frankfurt / Main
Monads
                                                           Scal
                                A simple Monad: Option




                                                                a
              def whereIs( name: String ) = {

                   projects.get( name )
                     .flatMap( project => customers get project )
                       .flatMap( customer => cities get customer )
                          .getOrElse( "unknown!" )
              }




Mario Gleichmann                                                     JUG Frankfurt / Main
Monads
                                                             Scal
                                A simple Monad: Option




                                                                   a
              def whereIs( name: String ) = {
                                              Results in Option[String]
                   projects.get( name )
                     .flatMap( project => customers get project )
                       .flatMap( customer => cities get customer )
                          .getOrElse( "unknown!" )
              }




Mario Gleichmann                                                          JUG Frankfurt / Main
Monads
                                                              Scal
                                 A simple Monad: Option




                                                                     a
              def whereIs( name: String ) = {
                                               Results in Option[String]
                   projects.get( name )
                     .flatMap( project => customers get project )
                       .flatMap( customer => cities get customer )
                          .getOrElse( "unknown!" )
              }

                     Option[A].map( A => B )          >> Option[B]



Mario Gleichmann                                                           JUG Frankfurt / Main
Monads
                                                                 Scal
                                 A simple Monad: Option




                                                                        a
              def whereIs( name: String ) = {
                                                  Results in Option[String]
                   projects.get( name )
                     .flatMap( project => customers get project )
                       .flatMap( customer => cities get customer )
                          .getOrElse( "unknown!" )
              }
                     Option[A].map( A => B )             >> Option[B]
                     Option[A].map( A => Option[B] )     >> Option[Option[B]]


Mario Gleichmann                                                              JUG Frankfurt / Main
Monads
                                                                 Scal
                                 A simple Monad: Option




                                                                         a
              def whereIs( name: String ) = {
                                                  Results in Option[String]
                   projects.get( name )
                     .flatMap( project => customers get project )
                       .flatMap( customer => cities get customer )
                          .getOrElse( "unknown!" )
              }
                     Option[A].map( A => B )              >> Option[B]
                     Option[A].map( A => Option[B] )      >> Option[Option[B]]
                    Option[A].flatMap( A => Option[B] )   >> Option[B]

Mario Gleichmann                                                              JUG Frankfurt / Main
Monads

                             Protected Composition




                   map( A => B )   map( B => C )    map( C => D )

                              None           None           None
                                                                     ...
              Some[A]        Some[B]       Some[C]         Some[D]




Mario Gleichmann                                                     JUG Frankfurt / Main
Monads

                                A simple Monad: Option

                   def whereIs( name: String ) =

                     (   for( project       <-   projects get name;
                              customer <-        customers get project;
                              city          <-   cities get customer
                            ) yield city
                     ).getOrElse( "unknown!" )




Mario Gleichmann                                                          JUG Frankfurt / Main
Summary

                              Scala allows for ...
            ●      Currying

            ●      Combinators

            ●      Fundamental Functions

            ●      Type classes

            ●      Monads


Mario Gleichmann                                     JUG Frankfurt / Main
Thank you !




Mario Gleichmann       111       JUG Frankfurt / Main
References


            Scala Home                www.scala-lang.org


            Dr. Erik Meijer           C9 Lectures – Functional Programming Fundamentals
                                      http://channel9.msdn.com


            Graham Hutton             Programming in Haskell
                                      Cambridge


            Odersky, Spoon, Venners   Programming in Scala
                                      artima




Mario Gleichmann                                     112                                  JUG Frankfurt / Main

Contenu connexe

Dernier

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Dernier (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

En vedette

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

En vedette (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Functional Scala II (in practice)

  • 1. Functional Scaλa … in Practice 20.10.2010 Java User Group Frankfurt / Main Mario Gleichmann Mario Gleichmann JUG Frankfurt / Main
  • 2. Introduction Mario Gleichmann site: www.mg-informatik.de blog: 'brain driven development' gleichmann.wordpress.com mail: mario.gleichmann@mg-informatik.de Mario Gleichmann 2 JUG Frankfurt / Main
  • 3. Summary Mario Gleichmann 3 JUG Frankfurt / Main
  • 4. What is Functional Programming ? Functional Style val sum = fold( 1 to 10, add ) Expression based Computation method is function application Mario Gleichmann 4 fcn JUG Frankfurt / Main
  • 5. What makes a Function ? Function Types val add = ( x :Int, y :Int ) => x + y Type of add : ( Int , Int ) => Int Mario Gleichmann 5 Obj JUG Frankfurt / Main
  • 6. Closures 'closing over' var limit = 18 val isAdult = ( age :Int ) => age >= limit 'Closed term' Mario Gleichmann 6 appl JUG Frankfurt / Main
  • 7. Algebraic Datatypes Example - Tree data Tree = Empty | Leaf Int | Node Int Tree Tree abstract case class Tree() case object Empty extends Tree case class Leaf( value: Int ) extends Tree case class Node( value: Int, left :Tree, right: Tree ) extends Tree Mario Gleichmann 7 insrt JUG Frankfurt / Main
  • 8. Pattern Matching val depth :Tree => Int = _ match { case Empty => 0 case Leaf( _ ) => 1 case Node( _, left, right ) => 1 + max( depth( left ), depth( right ) ) } Mario Gleichmann 8 Prt isb JUG Frankfurt / Main
  • 9. Partial Functions type =>?[-A, +B] = PartialFunction[A, B] val publisherRegionDE : Isbn =>? String = { case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 ) } … publisherRegionDE.isDefinedAt( Isbn( 0, 677873, 8823 ) ) ) >> false Mario Gleichmann 9 chn JUG Frankfurt / Main
  • 10. Comprehensions val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x ... val prime = ( n :Int ) => factors( n ).toList == List( 1, n ) … val primes = (n :Int) => for( x <- (1 to n) if prime( x ) ) yield x Mario Gleichmann 10 Hgh rdr Fcn JUG Frankfurt / Main
  • 11. Higher Order Functions val filter = ( predicate: Int => Boolean , xs :List[Int] ) => { for( x <- xs; if predicate( x ) ) yield x } Mario Gleichmann 11 Fcn Tp JUG Frankfurt / Main
  • 12. Lambda Expressions filter( num => num % 2 == 0, List( 1, 2, 3, 4, 5, 6 ) ) … filter( _ > 0, List( -1, 5, 0, -3, 7 ) ) Mario Gleichmann 12 fst arg JUG Frankfurt / Main
  • 13. Partial Application Mario Gleichmann 13 JUG Frankfurt / Main
  • 14. Partial Application val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) Type of isPrime: Int => Boolean Mario Gleichmann 14 def prms wthn JUG Frankfurt / Main
  • 15. Partial Application Delegation val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs ) Type of filter: ( Int => Boolean, List[Int] ) => List[Int] Mario Gleichmann 15 fxd var JUG Frankfurt / Main
  • 16. Partial Application Delegation val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs ) fixed variable Mario Gleichmann 16 appl nappl JUG Frankfurt / Main
  • 17. Partial Application New from Old ... val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = filter( isPrime, _ :List[Int] ) applied unapplied Mario Gleichmann 17 Fcn Tp JUG Frankfurt / Main
  • 18. Partial Application New from Old ... val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = filter( isPrime, _ :List[Int] ) Type of primesWithin: List[Int] => List[Int] Mario Gleichmann 18 Crrng JUG Frankfurt / Main
  • 19. Currying Mario Gleichmann 19 JUG Frankfurt / Main
  • 20. Currying val filter = ( pred: Int => Boolean , xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean , List[Int] ) => List[Int] Mario Gleichmann 20 Crrd fcn JUG Frankfurt / Main
  • 21. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Mario Gleichmann 21 Crrd fcn Tp JUG Frankfurt / Main
  • 22. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => ( List[Int] ) => List[Int] Mario Gleichmann 22 sngl arg JUG Frankfurt / Main
  • 23. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => ( List[Int] ) => List[Int] Curried Function Curried Function Mario Gleichmann 23 sngl xpln arg JUG Frankfurt / Main
  • 24. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => ( List[Int] ) => List[Int] ... accepting one ... resulting in another A function (Function) Arg function Mario Gleichmann 24 lmbd xpr JUG Frankfurt / Main
  • 25. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] ... is defined as a Lambda expession Mario Gleichmann 25 cls ovr JUG Frankfurt / Main
  • 26. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] ... closes over to Arguments (Scope) of surrounding Function 'filter' Mario Gleichmann 26 Smp prms wthn JUG Frankfurt / Main
  • 27. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) Mario Gleichmann 27 Fcn Tp JUG Frankfurt / Main
  • 28. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) Type of primesWithin: List[Int] => List[Int] Mario Gleichmann 28 appl JUG Frankfurt / Main
  • 29. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) ... primesWithin( List( 3, 4, 5, 6, 7 ) ) >> List( 3, 5, 7 ) Mario Gleichmann 29 Smp rc mgmt JUG Frankfurt / Main
  • 30. Example 2 – Ressource Management val initQuery = (dataSource :DataSource) => (query :String) => ( extractor :ResultSet => Unit ) => { try{ val conn = dataSource.getConnection val stmt = conn.createStatement val resultSet = stmt.executeQuery( query ) extractor( resultSet ) } finally{ try{ if( conn != null ) conn.close } finally{ if( stmt != null ) stmt.close } } } Mario Gleichmann 30 appl JUG Frankfurt / Main
  • 31. Example 2 – Ressource Management val dataSource :DataSource = ...; ... val query = initQuery( dataSource ) … query( "select * from User where age > 18" ) { result :ResultSet => while( result.next ) { .... } } … query( "select * from Account where balance < 1000" ) { result :ResultSet => while( result.next ) { .... } } Mario Gleichmann 31 smmy JUG Frankfurt / Main
  • 32. Combinators Mario Gleichmann 32 JUG Frankfurt / Main
  • 33. Combinators val power : Int => Int => Int = ( base :Int ) => ( exp :Int ) => if( exp == 1 ) base else base * power( base )( exp - 1 ) ... val square = power( _ :Int )( 2 ) Mario Gleichmann 33 JUG Frankfurt / Main
  • 34. Combinators val power : Int => Int => Int = ( base :Int ) => ( exp :Int ) => if( exp == 1 ) base else base * power( base )( exp - 1 ) ... val square = power( _ :Int )( 2 ) Type of square : Int => Int Mario Gleichmann 34 JUG Frankfurt / Main
  • 35. Combinators val power : Int => Int => Int = ( base :Int ) => ( exp :Int ) => if( exp == 1 ) base else base * power( base )( exp - 1 ) ... val square = power( _ :Int )( 2 ) Partial Application 'in the middle' Mario Gleichmann 35 JUG Frankfurt / Main
  • 36. Combinators def flipArgs [A, B, C] ( f: A => B => C ) : B => A => C = ( x: B ) => ( y: A ) => f (y) (x) Transforms to another Function, expecting arguments in reversed order Mario Gleichmann 36 JUG Frankfurt / Main
  • 37. Combinators def flipArgs [A, B, C] ( f: A => B => C ) : B => A => C = ( x: B ) => ( y: A ) => f (y) (x) … val square = flipArgs( power )( 2 ) … now just exploit Currying Mario Gleichmann 37 JUG Frankfurt / Main
  • 38. Combinators Function Composition f :: B => C g :: A => B x ∈ A ( f o g )( x ) = f ( g ( x ) ) ( f o g ) :: A => C Mario Gleichmann 38 JUG Frankfurt / Main
  • 39. Combinators : Function Composition def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C = ( x :A ) => f( g( x ) ) ... val mult = ( x :Int ) => ( y: Int ) => x * y val add = ( x :Int ) => ( y: Int ) => x + y ... val doubleSucc = o ( mult(2) ) ( add(1) ) Type of doubleSucc : Int => Int Mario Gleichmann 39 JUG Frankfurt / Main
  • 40. Combinators : Function Composition def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C = ( x :A ) => f( g( x ) ) ... val mult = ( x :Int ) => ( y: Int ) => x * y val add = ( x :Int ) => ( y: Int ) => x + y ... val doubleSucc = o ( mult(2) ) ( add(1) ) doubleSucc( 7 ) >> 16 Mario Gleichmann 40 JUG Frankfurt / Main
  • 41. Combinators : Function Composition def o [A,B,C] ( f: B => C ) ( g: A => B ) : A => C = ( x :A ) => f( g( x ) ) ... val mult = ( x :Int ) => ( y: Int ) => x * y val add = ( x :Int ) => ( y: Int ) => x + y ... val doubleSucc = o ( mult(2) ) ( add(1) ) doubleSucc( 7 ) Postfix ... >> 16 Mario Gleichmann 41 JUG Frankfurt / Main
  • 42. Combinators : Function Composition class RichFunc [B, C] ( f: B => C ) { def o[A] ( g: A => B ) = (x :A) => f( g( x ) ) } implicit def toRichFunc[B,C]( f: B => C ) = new RichFunc( f ) ... val doubleSucc = mult(2) o add(1) doubleSucc( 7 ) Infix !!! >> 16 Mario Gleichmann 42 JUG Frankfurt / Main
  • 43. Combinators : Function Composition class RichFunc [B, C] ( f: B => C ) { def o[A] ( g: A => B ) = (x :A) => f( g( x ) ) } implicit def toRichFunc[B,C]( f: B => C ) = new RichFunc( f ) ... val doubleSucc = mult(2) o add(1) doubleSucc( 7 ) 'Point free style' of function definition >> 16 Mario Gleichmann 43 JUG Frankfurt / Main
  • 44. Example: Word Counter Count all even words within a sentence: “Hello World“ → 0 “The fox jumps over the lazy dog“ → 2 "This sentence contains five even words" → 5 Mario Gleichmann 44 JUG Frankfurt / Main
  • 45. Example: Word Counter Count all even words within a sentence: “Hello World“ → 0 “The fox jumps over the lazy dog“ → 2 "This sentence contains five even words" → 5 Basic Functions: parse Words → Word to length → filter even → count Mario Gleichmann 45 JUG Frankfurt / Main
  • 46. Example: Word Counter Basic Functions val words = ( sentence : String ) => sentence.split( " " ).toList val length = ( ws :List[String] ) => for( w <- ws ) yield w.length val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ... val even = ( i :Int ) => i % 2 == 0 val size = ( xs :List[ _ ] ) => xs.size Mario Gleichmann 46 JUG Frankfurt / Main
  • 47. Example: Word Counter val words = ( sentence : String ) => sentence.split( " " ).toList val length = ( ws :List[String] ) => for( w <- ws ) yield w.length val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ... val even = ( i :Int ) => i % 2 == 0 val size = ( xs :List[ _ ] ) => xs.size val evenWordCount = size o filter( even ) o length o words Type of evenWordCount : String => Int Mario Gleichmann 47 JUG Frankfurt / Main
  • 48. Example: Word Counter val words = ( sentence : String ) => sentence.split( " " ).toList val length = ( ws :List[String] ) => for( w <- ws ) yield w.length val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ... val even = ( i :Int ) => i % 2 == 0 val size = ( xs :List[ _ ] ) => xs.size val evenWordCount = size o filter( even ) o length o words vs. val evenWordCount = (sentence :String ) => size ( filter( even ) ( length( words( sentence ) ) ) ) Mario Gleichmann 48 JUG Frankfurt / Main
  • 49. Example: Word Counter val words = ( sentence : String ) => sentence.split( " " ).toList val length = ( ws :List[String] ) => for( w <- ws ) yield w.length val filter = ( predicate: Int => Boolean ) => ( xs :List[Int] ) => ... val even = ( i :Int ) => i % 2 == 0 val size = ( xs :List[ _ ] ) => xs.size val evenWordCount = size o filter( even ) o length o words evenWordCount( "this sentence contains five even words" ) >> 5 Mario Gleichmann 49 JUG Frankfurt / Main
  • 50. Fundamental Functions Mario Gleichmann 50 JUG Frankfurt / Main
  • 51. Fundamental Functions def sum ( list : List[Int] ) : Int = list match { case Nil => 0 case x :: xs => x + sum( xs ) } Mario Gleichmann 51 JUG Frankfurt / Main
  • 52. Fundamental Functions def product ( list : List[Int] ) : Int = list match { case Nil => 1 case x :: xs => x * product( xs ) } Mario Gleichmann 52 JUG Frankfurt / Main
  • 53. Fundamental Functions def allTrue ( ys : List[Boolean] ) : Boolean = ys match { case Nil => true case x :: xs => x and allTrue( xs ) } Mario Gleichmann 53 JUG Frankfurt / Main
  • 54. Fundamental Functions : reduce def reduce ( list : List[ T ] ) : R = list match { case Nil => ? case x :: xs => x ʘ reduce( xs ) } Mario Gleichmann 54 JUG Frankfurt / Main
  • 55. Fundamental Functions : reduce def reduce ( list : List[ T ] ) : R = list match { case Nil => ? 'unit' case x :: xs => x ʘ reduce( xs ) } 'subsuming operation' Mario Gleichmann 55 JUG Frankfurt / Main
  • 56. Fundamental Functions : reduce def reduce[T,R] ( fun : T => R => R ) ( unit : R ) ( list : List[T] ) : R = list match { case Nil => unit case x :: xs => fun ( x ) ( reduce( fun )( unit )( xs ) ) } Mario Gleichmann 56 JUG Frankfurt / Main
  • 57. Fundamental Functions : reduce def reduce[T,R] ( fun : T => R => R ) ( unit : R ) ( list : List[T] ) : R = list match { case Nil => unit case x :: xs => fun ( x ) ( reduce( fun )( unit )( xs ) ) } reduce ʘ unit t1 :: t2 :: t3 :: t4 :: Nil => t1 ʘ ( t2 ʘ ( t3 ʘ ( t4 ʘ unit ) ) ) Mario Gleichmann 57 JUG Frankfurt / Main
  • 58. Fundamental Functions : reduce val add = (x : Int) => (y : Int) => x + y val mult = (x : Int) => (y : Int) => x * y ... val sum = reduce ( add ) ( 0 ) _ val product = reduce ( mult ) ( 1 ) _ ... sum( List( 1, 2, 3, 4 ) ) >> 10 product( List( 1, 2, 3, 4 ) ) >> 24 Mario Gleichmann 58 JUG Frankfurt / Main
  • 59. Fundamental Functions : reduce val or = ( x :Boolean ) => ( y :Boolean ) => x || y val and = ( x :Boolean ) => ( y :Boolean ) => x && y val not = ( x :Boolean ) => !x ... val existOneTrue = reduce ( or ) ( false ) _ val allFalse = not o reduce ( or ) ( false ) _ val allTrue = reduce ( and ) ( true ) _ ... allTrue( List( 1 < 2, 3 == 3, 1 + 1 == 2 ) ) >> true Mario Gleichmann 59 JUG Frankfurt / Main
  • 60. Example: List concatenation def append[T] (x:T) (xs:List[ _ ]) = x :: xs val listConcat = reduce ( append ) _ listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) >> List( 8, 9, 1, 2, 3, 4 ) listConcat ( List( true, true, false ) ) ( List( true, false ) ) ) >> List( true, false, true, true, false ) Mario Gleichmann 60 JUG Frankfurt / Main
  • 61. Example: List concatenation def append[T] (x:T) (xs:List[ _ ]) = x :: xs val listConcat = reduce ( append ) _ listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) >> List( 8, 9, 1, 2, 3, 4 ) 'unit' listConcat ( List( true, true, false ) ) ( List( true, false ) ) ) >> List( true, false, true, true, false ) Mario Gleichmann 61 JUG Frankfurt / Main
  • 62. Example: List concatenation def append[T] (x:T) (xs:List[ _ ]) = x :: xs val listConcat = flipArgs( reduce ( append ) _ ) listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) >> List( 1, 2, 3, 4, 8, 9 ) listConcat ( List( true, true, false ) ) ( List( true, false ) ) ) >> List( true, true, false, true, false ) Mario Gleichmann 62 JUG Frankfurt / Main
  • 63. Example: List concatenation def append[T] (x:T) (xs:List[ _ ]) = x :: xs val listConcat = flipArgs( reduce ( append ) _ ) listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) >> List( 1, 2, 3, 4, 8, 9 ) 'unit' listConcat ( List( true, true, false ) ) ( List( true, false ) ) ) >> List( true, true, false, true, false ) Mario Gleichmann 63 JUG Frankfurt / Main
  • 64. Example: List concatenation ! def append[T] (x:T) (xs:List[ _ ]) = x :: xs val listConcat = flipArgs( reduce ( append ) _ ) listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) Type of result: List[Any] Mario Gleichmann 64 JUG Frankfurt / Main
  • 65. Example: List concatenation def append[T] (x:T) (xs:List[ T ]) = x :: xs def listConcat[A] ( a: List[A]) ( b: List[A] ) : List[A] = reduce[ A, List[A] ] ( ( append[A] ) _ ) (b) (a) listConcat ( List( 1, 2, 3, 4 ) ) ( List( 8, 9 ) ) ) Type of result: List[Int] Mario Gleichmann 65 JUG Frankfurt / Main
  • 66. More Fundamental Functions Mario Gleichmann 66 JUG Frankfurt / Main
  • 67. Fundamental Functions val doubleAll : List[Int] => List[Int] = _ match { case Nil => Nil case y :: ys => y * 2 :: doubleAll( ys ) } doubleAll( List( 1, 2, 3, 4 ) ) >> List( 2, 4, 6, 8 ) Mario Gleichmann 67 JUG Frankfurt / Main
  • 68. Fundamental Functions val toLength : List[String] => List[Int] = _ match { case Nil => Nil case y :: ys => y.length :: toLength( ys ) } toLength( List( "a", "ab", "abc", "abcde" ) ) ) >> List( 1, 2, 3, 5 ) Mario Gleichmann 68 JUG Frankfurt / Main
  • 69. Fundamental Functions : map val map : List[T] => List[R] = _ match { case Nil => Nil case y :: ys => f?( y ) :: map( ys ) } Mario Gleichmann 69 JUG Frankfurt / Main
  • 70. Fundamental Functions : map def map[T, R] ( f: T => R ) : List[T] => List[R] = ( xs : List[T] ) => xs match { case Nil => Nil case y :: ys => f( y ) :: map( f )( ys ) } Mario Gleichmann 70 JUG Frankfurt / Main
  • 71. Fundamental Functions : map def map[T, R] ( f: T => R ) : List[T] => List[R] = ( xs : List[T] ) => xs match { case Nil => Nil case y :: ys => f( y ) :: map( f )( ys ) } Accepting a function to Resulting in another function, apply on every element accepting the List of elements Mario Gleichmann 71 JUG Frankfurt / Main
  • 72. Fundamental Functions : map def map[T, R] ( f: T => R ) : List[T] => List[R] = ... ... val mult = (x : Int) => (y : Int) => x * y val doubleAll = map( mult( 2 ) ) ... val toLength = map( ( s :String ) => s.length ) Mario Gleichmann 72 JUG Frankfurt / Main
  • 73. Fundamental Functions : map val add = (x : Int) => (y : Int) => x + y val sum = reduce ( add ) ( 0 ) _ val sumMatrix = sum o map( sum ) Type of sum : List[Int] => Int Type of map( sum ) : List[List[Int]] => List[Int] Type of sumMatrix : List[List[Int]] => Int Mario Gleichmann 73 JUG Frankfurt / Main
  • 74. Fundamental Functions : map val add = (x : Int) => (y : Int) => x + y val sum = reduce ( add ) ( 0 ) _ val sumMatrix = sum o map( sum ) ... val matrix = List( List( 1, 2, 3 ), List( 4, 5, 6 ), List( 7, 8, 9 ) ) sumMatrix( matrix ) >> 45 Mario Gleichmann 74 JUG Frankfurt / Main
  • 75. map via reduce def applyAndPrepend [A, B] ( f: A => B ) = ( a :A ) => ( bs :List[B] ) => f( a ) :: bs def map [A, B] ( f: A => B ) : List[A] => List[B] = reduce ( applyAndPrepend( f ) ) ( Nil ) _ Mario Gleichmann 75 JUG Frankfurt / Main
  • 76. map via reduce def applyAndPrepend [A, B] ( f: A => B ) = ( a :A ) => ( bs :List[B] ) => f( a ) :: bs def map [A, B] ( f: A => B ) : List[A] => List[B] = reduce ( applyAndPrepend( f ) ) ( Nil ) _ f :: f :: f :: f :: Nil X1 :: X2 :: X3 :: X4 :: Nil Mario Gleichmann 76 JUG Frankfurt / Main
  • 77. filter via reduce def filter[T]( pred :T => Boolean ) : List[T] => List[T] = reduce ( ( x :T ) => ( acc :List[T] ) => if( pred( x ) ) x :: acc else acc ) ( Nil ) Mario Gleichmann 77 JUG Frankfurt / Main
  • 78. Type Classes Mario Gleichmann 78 JUG Frankfurt / Main
  • 79. Type Classes def sum( xs : List[Int] ) : Int = xs match { case Nil => 0 case head :: tail => head + sum( tail ) } Mario Gleichmann 79 JUG Frankfurt / Main
  • 80. Type Classes def sum( xs : List[String] ) : String = xs match { case Nil => ““ case head :: tail => head + sum( tail ) } Concatenation ! Mario Gleichmann 80 JUG Frankfurt / Main
  • 81. Type Classes def sum[A]( xs : List[A] ) : A = xs match { case Nil => ? case head :: tail => head ? sum( tail ) } Mario Gleichmann 81 JUG Frankfurt / Main
  • 82. Type Classes def sum[A]( xs : List[A] ) : A = xs match { case Nil => ? 'neutral' element case head :: tail => head ? sum( tail ) } element composition Mario Gleichmann 82 JUG Frankfurt / Main
  • 83. Type Classes trait SemiGroup[S] { def add( x : S, y : S ) : S element composition } trait Monoid[M] extends SemiGroup[M] { def unit : M 'neutral' element } Mario Gleichmann 83 JUG Frankfurt / Main
  • 84. Type Classes def sum [A] ( xs : List[A], m: Monoid[A] ) : A = xs match { case Nil => m.unit case head :: tail => m.add( head, sum( tail, m) ) } Mario Gleichmann 84 JUG Frankfurt / Main
  • 85. Type Classes def sum [A] ( xs : List[A], m: Monoid[A] ) : A = 'type constraint' xs match { case Nil => m.unit case head :: tail => m.add( head, sum( tail, m) ) } Mario Gleichmann 85 JUG Frankfurt / Main
  • 86. Type Classes object IntMonoid extends Monoid[Int]{ def add(x : Int, y : Int): Int = x + y def unit : Int = 0 } … sum( List( 1, 2, 3, 4 ), IntMonoid ) Mario Gleichmann 86 JUG Frankfurt / Main
  • 87. Type Classes def sum [A] ( xs : List[A] ) ( implicit m: Monoid[A] ) : A = ... implicit object IntMonoid extends Monoid[Int]{ … } … import typeclasses.monoid._ ... sum( List( 1, 2, 3, 4 ) ) Mario Gleichmann 87 JUG Frankfurt / Main
  • 88. Example: Clock-Monoid sealed abstract case class ClockHour( hour: Int ) case object HOUR_0 extends ClockHour( 0 ) case object HOUR_1 extends ClockHour( 1 ) ... case object HOUR_11 extends ClockHour( 11 ) … implicit object ClockHourMonoid extends Monoid[ClockHour]{ val hours = Array( HOUR_0, HOUR_1, HOUR_2, ..., HOUR_11 ) def add(x : ClockHour, y : ClockHour) = hours( ( x.hour + y.hour ) % 12 ) def unit : ClockHour = HOUR_0 } Mario Gleichmann 88 JUG Frankfurt / Main
  • 89. Example: Clock-Monoid import typeclasses.monoid.ClockHourMonoid ... sum( List( HOUR_5, HOUR_3, HOUR_8 ) ) >> HOUR_4 Mario Gleichmann 89 JUG Frankfurt / Main
  • 90. Example: Contains element ? trait Eq[E]{ def equals( e1 :E, e2 :E ) : Boolean } def contains [T] ( x :T, xs : List[T] ) ( implicit eq :Eq[T] ) : Boolean = reduce ( ( y :T ) => ( acc :Boolean ) => if( eq.equals( x, y ) ) true else acc ) ( false ) 1st Arg: 'reducing' function ( xs ) 2nd Arg: 'unit' 3rd Arg: List to reduce Mario Gleichmann 90 JUG Frankfurt / Main
  • 91. Example: Contains element ? case class Person( name :String, age :Int ) implicit object PersonEq extends Eq[Person]{ def equals( p1 :Person, p2 :Person ) : Boolean = (p1.name == p2.name) && (p1.age == p2.age) } ... val persons = List( Person("Hans", 22), Person( "Helga", 32 ), Person( "Hugo", 47 ) ) contains( Person( "Olga", 22 ), persons ) >> false contains( Person( "Helga", 32 ), persons ) >> true Mario Gleichmann 91 JUG Frankfurt / Main
  • 92. Monads Mario Gleichmann 92 JUG Frankfurt / Main
  • 93. Monads A simple Monad: Option << abstract >> Option[+A] Some[+A] None presence absence Handling the or of something ...as the result of a computation (computational environment) Mario Gleichmann JUG Frankfurt / Main
  • 94. Monads A simple Monad: Option class CustomerDAO{ def findCustomer( custId: Long ) : Option<Customer> = { ... if( found( customer ) ) Some( customer ) else None } } Mario Gleichmann JUG Frankfurt / Main
  • 95. Monads A simple Monad: Option class CustomerDAO{ def findCustomer( custId: Long ) : Option<Customer> = { ... if( found( customer ) ) Some( customer ) else None } } Explicit Notion, that there may be 'none' result Mario Gleichmann JUG Frankfurt / Main
  • 96. Monads A simple Monad: Option val customerHit = customerDAO.findCustomer( 123 ); ... customerHit match { case Some( customer ) => println( customer.name ) case None => println( “not found“ ) } Mario Gleichmann JUG Frankfurt / Main
  • 97. Monads A simple Monad: Option val customerHit = customerDAO.findCustomer( 123 ); ... customerHit match { case Some( customer ) => println( customer.name ) case None => println( “not found“ ) } Explicit Handling the absensce of a result Forces 'Awareness' Mario Gleichmann JUG Frankfurt / Main
  • 98. Monads A simple Monad: Option val customerHit = customerDAO.findCustomer( 123 ); ... customerHit match { case Some( customer ) => println( customer.name ) case None => println( “not found“ ) } ... beside from that ... what's the deal ??? Mario Gleichmann JUG Frankfurt / Main
  • 99. Monads A simple Monad: Option val customerHit = customerDAO.findCustomer( 123 ); ... customerHit match { case Some( customer ) => println( customer.name ) case None => println( “not found“ ) } 'Protected' Function Composition ... Mario Gleichmann JUG Frankfurt / Main
  • 100. Monads val projects = Map( "Jan" -> "IKT", "Joe" -> "TensE", "Luca" -> "InTA" ) val customers = Map( "IKT" -> "Hanso GmbH", "InTA" -> "RAIA Duo" ) val cities = Map( "Hanso GmbH" -> "Stuttgart", "Mogno" -> "Mailand" ) Mario Gleichmann JUG Frankfurt / Main
  • 101. Monads val projects = Map( "Jan" -> "IKT", "Joe" -> "TensE", "Luca" -> "InTA" ) val customers = Map( "IKT" -> "Hanso GmbH", "InTA" -> "RAIA Duo" ) val cities = Map( "Hanso GmbH" -> "Stuttgart", "Mogno" -> "Mailand" ) Where is Jan ? Jan -> IKT -> Hanso GmbH -> Stuttgart Mario Gleichmann JUG Frankfurt / Main
  • 102. Monads Jav public String whereIs( String name ){ a String project = projects.get( name ); if( project != null ){ String customer = customers.get( project ); if( customer != null ){ String city = cities.get( customer ) if( city != null ) return city; else return “unknown“; } else return ''unknown''; } else return ''unknown''; } Mario Gleichmann JUG Frankfurt / Main
  • 103. Monads Scal A simple Monad: Option a def whereIs( name: String ) = { projects.get( name ) .flatMap( project => customers get project ) .flatMap( customer => cities get customer ) .getOrElse( "unknown!" ) } Mario Gleichmann JUG Frankfurt / Main
  • 104. Monads Scal A simple Monad: Option a def whereIs( name: String ) = { Results in Option[String] projects.get( name ) .flatMap( project => customers get project ) .flatMap( customer => cities get customer ) .getOrElse( "unknown!" ) } Mario Gleichmann JUG Frankfurt / Main
  • 105. Monads Scal A simple Monad: Option a def whereIs( name: String ) = { Results in Option[String] projects.get( name ) .flatMap( project => customers get project ) .flatMap( customer => cities get customer ) .getOrElse( "unknown!" ) } Option[A].map( A => B ) >> Option[B] Mario Gleichmann JUG Frankfurt / Main
  • 106. Monads Scal A simple Monad: Option a def whereIs( name: String ) = { Results in Option[String] projects.get( name ) .flatMap( project => customers get project ) .flatMap( customer => cities get customer ) .getOrElse( "unknown!" ) } Option[A].map( A => B ) >> Option[B] Option[A].map( A => Option[B] ) >> Option[Option[B]] Mario Gleichmann JUG Frankfurt / Main
  • 107. Monads Scal A simple Monad: Option a def whereIs( name: String ) = { Results in Option[String] projects.get( name ) .flatMap( project => customers get project ) .flatMap( customer => cities get customer ) .getOrElse( "unknown!" ) } Option[A].map( A => B ) >> Option[B] Option[A].map( A => Option[B] ) >> Option[Option[B]] Option[A].flatMap( A => Option[B] ) >> Option[B] Mario Gleichmann JUG Frankfurt / Main
  • 108. Monads Protected Composition map( A => B ) map( B => C ) map( C => D ) None None None ... Some[A] Some[B] Some[C] Some[D] Mario Gleichmann JUG Frankfurt / Main
  • 109. Monads A simple Monad: Option def whereIs( name: String ) = ( for( project <- projects get name; customer <- customers get project; city <- cities get customer ) yield city ).getOrElse( "unknown!" ) Mario Gleichmann JUG Frankfurt / Main
  • 110. Summary Scala allows for ... ● Currying ● Combinators ● Fundamental Functions ● Type classes ● Monads Mario Gleichmann JUG Frankfurt / Main
  • 111. Thank you ! Mario Gleichmann 111 JUG Frankfurt / Main
  • 112. References Scala Home www.scala-lang.org Dr. Erik Meijer C9 Lectures – Functional Programming Fundamentals http://channel9.msdn.com Graham Hutton Programming in Haskell Cambridge Odersky, Spoon, Venners Programming in Scala artima Mario Gleichmann 112 JUG Frankfurt / Main