## Scala

### syntax

#### functional traits

- interfaces for functions
- we introduce data types with [traits]

- sealed trait

- sealed means that all implentations must be in this file, kinda the same as [dinal]

#### other syntax quirks

- each anonymous function has a implicit [apply] method that exposes the interface or [trait] of the function
- the function apply means that a function object can be called implicitly
- square brackets with capitals signify [generics]/[polymorphic] functions
- remember that anonymous functions should be wrapped in [brackets] and can name arguments only at [top] level
- note that applying 1 function after another requires repeated use of [brackets]

def uncurry[A,B,C](f: A => B=> C): (A,B)=>C = (a:A,b:B) => f (a) (b)

#### data constructors

- varying forms use the case statement
- think overloading constructors

- are made by [extend]ing the trait
- each data constructor introduces a pattern

#### collections

- lists

- lists can be made [polymorphic] with square brackets
- adding a + makes the list [covariant]
- We defined Nil to extend List[Nothing]
- Nothing mathes all types
- Therefore because list is covarient
- Nil has a type [List[A]] for any A

- Variadic functions

what does _* mean?//recursively applies cons def apply[A](as: A*): List[A] = if (as.isEmpty) Nil else Cons(as.head, apply(as.tail: _*)) }

- The Answer

- * is just syntatic sugar for a Seq which are lists or array like structures passed around instead of variable arguments
- as is bound to Seq[A] http://mng.bz/f4k9
- _~* allows us to pass a Seq to a varargs method,
- a bit like pythonic **

- The Answer

- covariance

- generally if X is a subtype of Y then
- List[X] is a subtupe of List[Y]

- generally if X is a subtype of Y then

- companion objects

- has the same [name] as our data type
- also has [convience] functions

- constructor quirks

why is Nil defined with object a and list defined via class- The Answer

- pattern matching

- _ matches any value

def sum(ints:List[Int]):Int = ints match { case Nil => 0 case Cons(x,xs) => x + sum(xs) }

- syntatical quirks

- need the ints for the match clause -called the [target] or [scrutinee]
- case statements

- currying

- is done by sepearting out curried terms using [brackets]
- apparently currying makes type infrerence work better

call curried items via g(a) (b)

- foldRight

- replaces cons with f and Nil with its intialiser
- foldRight must traverse all the way to the end of the list (pushing frames onto the call stack as we go) before it can begin collapsing it

def foldRight[A,B](as: List[A], z: B)(f: (A, B) => B): B = as match { case Nil => z case Cons(x, xs) => f(x, foldRight(xs, z)(f)) }

- foldLeft

- pretty much sampe as fold right
- word on the street is that foldl is broken
- foldl is broken! http://bit.ly/PdqGMB a

- but moves computation inside recurusion
- forcing early evaluation
- use initialiser as an accumulator

def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match { case Nil => z case Cons(x,xs) => foldLeft( xs, f(z, x)) (f) }

#### algebraeic data types

- definition

- a datatype with one or more constructors
- a type is the sum of its construstors
- each constructor is the product of its arguments

#### notes on exercises

- Exercise 23

was unable to define addlists in terms of map foldmap perhaps there is another way?def addLists(a:List[Int], b:List[Int]): List[Int] = a match { case Nil => b case Cons(x,xs) => Cons(x+ head(b), addLists(xs, tail(b))) }

- The Answer

- Exercise 24

compiler cant find scanRightdef hasSubsequence[A](l: List[A], sub: List[A]): Boolean = scanRight (l,Nil:List[A]) ((a:A, b:List[B]) => Cons(a,b)) exists ((c:List[A]) => c == l)

- The Answer

Advertisements