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] }
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.