31
- function里面的参数实际上都是只有一个的,然后使用pattern matching来进行操作,这也是函数能够返回多个值的原理。
32 type inference
- 不适用pattern match的话就要specify参数的个数,
- patten match里面没有出现的参数可以是任何参数, unexpected polymorphism..
33 polymorphism
- not ok to use 'a type in different types, should be the SAME in the context
- always choose the type which is more loose, or bigger
equality type 可以用= 比较的类型, ''a
34 nested patterns
- do it elegantly.
- 3个以上的pattern?
- leave the last condition in one.
37 function binding
- just another way of case expression.
- not overload function?
38 exception
- define yourself an exception
- raise & handle
39 tail recursion
- on call stack
fun fact n = if n = 0 then 1 else n* fact(n-1)
fun fact n =
let fun aux (n, acc) =
if n = 0
then acc
else aux(n-1, acc*n)
in
aux(n, 1)
end
- tail recursion is as efficient as a loop => no call stack!
- remove the caller before the call ends, since the callee's result will be returned without any evaluation
- recognize tail recursion from compiler
Sometimes you could not write tail recursive function...
42 functions
- first-class functions, use as argument
- function closure
- high order function, polymorphic
- some polymorphic functions are not high-order
45 anonymous functions
fn x => 3*x
- no recursive, (no name)
- unnecessary function wrapping, (use the original name)
47 map & filter
49 lexical scope
- the function's value will not be mutated, it is depend on the environment where it is defined.
- closure, no dynamic scope
- the condition will be recomputed
53 fold
- iterator like programming paradigm, apply parameter to each order
55 currying
multiple arguments
fun f x y z = x>y andalso y > z
fun f (x, y, z) = x>y andalso y > z
56 partial application
function with part parameter as function instanitiated
not work with polymorphic functions
57 currying wrapup
和tuple封装的替换,或者参数的顺序替换
58 mutable references
t ref // t is a type
ref e
e1 := e2
!e
59 callbacks
val cbs : (int -> unit) list ref = ref []
fun onEvent i =
let fun loop fs =
case fs of
[] => ()
| f::fs' => (f i; loop fs')
in loop (!cbs) end
fun onKeyEvent f =
cbs := f::(!cbs)
val timePressed = ref 0
val _ = onKeyEvent(fn _ => timePressed := !timePressed + 1)
fun printIfPressed i =
onKeyEvent (fn j =>
if i = j
then print ("pressed" ^ Int.toString i ^ "
")
else ()
)