/* Due note sull' if ... then ... else ... /* operatori booleani not, andalso e orelse /* clausola else non opzionale /* overloading # interi negativi ~ - fun abs x = if x < 0 then ~x else x; > val abs = fn : int -> int # le costanti reali si riconoscono dal . - fun absr x = if x < 0.0 then ~x else x; > val absr = fn : real -> real - fun prod (x,y) = x*y; > val prod = fn : int * int -> int # le funzioni sono valori - prod; > val it = fn : int * int -> int # versione "currificata" del prodotto con due argomenti # invece di UN argomento coppia... - fun prodc x y = x*y; > val prodc = fn : int -> int -> int # dichiarazione esplicita di tipi: - fun rprod (x:real) y = x*y; > val rprod = fn : real -> real -> real # i rami dell'if DEVONO avere lo stesso tipo - if true then 3 else (); ! Toplevel input: ! if true then 3 else (); ! ^^ ! Type clash: expression of type ! unit ! cannot have type ! int # la condizione DEVE essere una espressione di tipo bool - if 3 then true else false; ! Toplevel input: ! if 3 then true else false ! ^ ! Type clash: expression of type ! int ! cannot have type ! bool #call by value - fun newif a b c = if a then b else c; > val 'a newif = fn : bool -> 'a -> 'a -> 'a # la chiamata a newif forza la valutazione dei paramentri... - fun fact n = newif (n=0) 1 (n* fact(n-1)); > val fact = fn : int -> int #... infatti: - fact 3; ! Uncaught exception: ! Out_of_memory # Ancora sullo scope - val x = 2; > val x = 2 :int # la variabile "x" nell'espressione "x+1" ha il valore prima # della dichiarazione "x=4" - val x =4 and y = x+1; > val x = 4 : int val y = 3 : int # Ancora sul pattern matching # i patterns sono solo espressioni che eventualmente # contengono variabili - val x = (true, 10); > val x = (true, 10) : bool * int - val (left, right) = x; > val left = true : bool val right = 10 : int # l'ordine dei pattern nelle funzioni definite per # pattern matching E' RILEVANTE: - fun fact n = n*fact(n-1) | fact 0 = 1; ! Toplevel input: ! ....fact n = n*fact(n-1) ! | fact 0 = 1. ! Warning: some cases are unused in this match. # n matcha con tutto, non viene MAI applicato il caso base > val fact = fn : int -> int - fact 3; ! Uncaught exception: ! Out_of_memory # records & record wildcards - val p = {name = "pippo", age=52}; > val p = {age = 52, name = "pippo"} : {age : int, name : string} - {name = "pippo", age=52} = p; > val it = true : bool # posso non conoscere tutti i campi del record, # isolando comunque il campo che mi interessa: - val {name = n, ...} = p; > val n = "pippo" : string # Polimorfismo: monotypes & polytypes # osservate che il secondo argomento puo' avere qualsiasi tipo - fun incFirst (x, y) = (x+1, y); > val 'a incFirst = fn : int * 'a -> int * 'a - nil; > val 'a it = [] : 'a list # qual e' la funzione piu' polimorfa? L'identita', certo... - fun id x = x; > val 'a id = fn : 'a -> 'a # notazione a' la lambda calcolo per i parametri: # ancora l'identita'... - val id = fn x => x; > val 'a id = fn : 'a -> 'a # Polimorfismo ed uguaglianza: le funzioni non ammettono ugualglianza # (notare il doppio apice nei tipi tornati dal compilatore): - fun uguale a b = a=b; > val ''a uguale = fn : ''a -> ''a -> bool - fun fst x y = x; > val ('a, 'b) fst = fn : 'a -> 'b -> 'a - val ufst = fn x => fn y => x; > val ('a, 'b) ufst = fn : 'a -> 'b -> 'a - uguale fst ufst; ! Toplevel input: ! uguale fst snd; ! ^^^ ! Type clash: expression of type ! 'a -> 'b -> 'a ! cannot have equality type ''c # qualche funzionale di ordine superiore: - fun compose f g x = f (g x); > val ('a, 'b, 'c) compose = fn : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b # definito con fn x =>... - val compose = fn f => fn g => fn x => f (g x); > val ('a, 'b, 'c) compose = fn : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b - val superfatt = compose fatt fatt; > val superfatt = fn : int -> int - superfatt 3; > val it = 720 : int # ecco un'altro funzionale per calcolare la sommatoria # f(1)+f(2)+...+f(n) - fun sommatoria f 0 = 0 | sommatoria f n = (f n) + sommatoria f (n-1); > val sommatoria = fn : (int -> int) -> int -> int # la sommatoria da 1 a n sarebbe semplicemente la funzione: val somm = sommatoria id; > val somm = fn: int -> int