Functional programming in Scala

Functional programming in Scala David Raymond Christiansen IT University of Copenhagen December 4, 2012 Methods and functions Methods are the fund...
Author: Deborah West
1 downloads 0 Views 269KB Size
Functional programming in Scala

David Raymond Christiansen IT University of Copenhagen December 4, 2012

Methods and functions

Methods are the fundamental thing that can be called, but they are not values! There is a difference between f and g in: object Test { def f(x: Int) = x val g = (x: Int) => x } Workaround: if f is a method, f(x) calls f on x. if f is not a method, f(x) translates to f.apply(x).

2

Functions and partial functions

Two main categories of functions: F UNCTIONS have an apply method and methods for composition PARTIAL FUNCTIONS can additionally be queried whether they are defined for an input.

3

Functions and partial functions Functions: (_.toInt + 7) x => x.toInt + 7 {x: String => x.toInt + 7} new (String => Int) { def apply(x: String) = x.toInt + 7 } Partial functions: { case x :: xs => true } { case x if x.forall(_.isDigit) => x.toInt + 7 } def expr: Parser[Int] = (constant | parens)~opt(op~expr) ^^ { case n~None => n case n~Some(f~m) => f(n, m) } 4

Uses for partial functions

I

PartialFunction is a subtype of function - conveniently use it as pattern-matching lambda!

I

lift turns a PartialFunction[A, B] into A => Option[B]

I

Collections define a collect method, that maps when the function is defined and filters when it isn’t

5

Type Classes Type classes in Haskell: class Functor f where fmap :: (a -> b) -> f a -> f b instance Functor [] where fmap = map instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing incrementF :: (Functor f) => f Int -> f Int incrementF = fmap (1+)

6

Type classes

Type classes can be encoded in Scala: I

The type class becomes a trait with at least one type parameter

I

Instances of the type class become implicit objects mixing in the trait

I

Type class constraints become implicit parameters

7

Functor in Scala

class Functor f where fmap :: (a -> b) -> f a -> f b becomes trait Functor[F[ ]] { def fmap[A, B](f: A => B): F[A] => F[B] }

8

Using Functor

def incrementF[F[ ]](x: F[Int]) (implicit inst: Functor[F]): F[Int] = inst.fmap((y: Int) => y + 1)(x)

9

Using Functor

def incrementF[F[ ]](x: F[Int]) (implicit inst: Functor[F]): F[Int] = inst.fmap((y: Int) => y + 1)(x)

Syntactic sugar: def incrementF[F[ ]:Functor](x: F[Int]): F[Int] = { val inst = implicitly[Functor[F]] inst.fmap((y: Int) => y + 1)(x) }

9

Sorted lists

object Module { sealed abstract class SortedList[A SortedList.cons(f(x), fmap(f)(xs)) } }

12

Bounded functors Let’s make SortedList into a functor: object SortedListFunctor extends Functor[SortedList] { def fmap[A EmptySorted() case Cons(x, xs) => SortedList.cons(f(x), fmap(f)(xs)) } } We need the bounds!

12

Bounded Functors

trait BoundedFunctor[Bound[ ], F[T M[B]): M[A] => M[B] } I

unit constructs a “simple” instance

I

bind does mapping and flattening (like flatMap, or C# SelectMany)

16

Homework

I

Implement the Monad type class and a few instances of it.

I

Find a way to enable instances of your monad to be used with for-notation. Hint: fuzzy hat!

I

Implement a set datatype as a tree, having the type parameter F-bounded by Ordered. Don’t worry about integrating it into the Scala collections hierarchy.

I

Implement a BoundedMonad, analagous to the BoundedFunctor from the lecture. Create an instance for your tree.

17