Sök…
Definiera en funktion med låtbindning
Värden kan anges med hjälp av let :
# let a = 1;;
val a : int = 1
Du kan använda liknande syntax för att definiera en funktion. Ge bara ytterligare parametrar för argumenten.
# let add arg1 arg2 = arg1 + arg2;;
val add : int -> int -> int = <fun>
Vi kan kalla det så här:
# add 1 2;;
- : int = 3
Vi kan skicka värden direkt in så, eller vi kan skicka värden bundna till namn:
# add a 2;;
- : int = 3
Linjen som tolkaren ger oss när vi definierar något är objektets värde med typsignatur. När vi gav det ett enkelt värde bundet till a , kom det tillbaka med:
val a : int = 1
Vilket betyder a är ett int , och dess värde är 1 .
Typsignaturen för vår funktion är lite mer komplicerad:
val add : int -> int -> int = <fun>
Typsignaturen för add ser ut som ett gäng ints och pilar. Detta beror på att en funktion som tar två argument faktiskt är en funktion som bara tar ett argument, men returnerar en annan funktion som tar nästa argument. Du kan istället läsa det så här:
val add : int -> (int -> int) = <fun>
Detta är användbart när vi vill skapa olika sorters funktioner under tiden. Till exempel en funktion som lägger till 5 till allt:
# let add_five = add 5;;
val add_five : int -> int = <fun>
# add_five 5;;
- : int = 10
# add_five 10;;
- : int = 15
Använda funktionen nyckelord
function automatiskt mönstermatchning när du definierar kroppen för din funktion. Observera det nedan:
# let foo = function
0 -> "zero"
| 1 -> "one"
| 2 -> "couple"
| 3 -> "few"
| _ -> "many";;
val foo : int -> bytes = <fun>
# foo 0;;
- : bytes = "zero"
# foo 3;;
- : bytes = "few"
# foo 10;;
- : bytes = "many"
# let bar = function
"a" | "i" | "e" | "o" | "u" -> "vowel"
| _ -> "consonant";;
val bar : bytes -> bytes = <fun>
# bar "a";;
- : bytes = "vowel"
# bar "k";;
- : bytes = "consonant"
Anonyma funktioner
Eftersom funktioner är vanliga värden finns det en bekväm syntax för att skapa funktioner utan namn:
List.map (fun x -> x * x) [1; 2; 3; 4]
(* - : int list = [1; 4; 9; 16] *)
Detta är praktiskt, eftersom vi annars skulle behöva namnge funktionen först (se låt ) för att kunna använda den:
let square x = x * x
(* val square : int -> int = <fun> *)
List.map square [1; 2; 3; 4]
(* - : int list = [1; 4; 9; 16] *)
Rekursiva och ömsesidigt rekursiva funktioner
Du kan definiera en funktion som ska vara rekursiv med nyckelordet rec , så att det kan kalla sig själv.
# let rec fact n = match n with
| 0 -> 1
| n -> n * fact (n - 1);;
val fact : int -> int = <fun>
# fact 0;;
- : int = 1
# fact 4;;
- : int = 24
Du kan också definiera ömsesidigt rekursiva funktioner med and sökord, så att de kan ringa varandra.
# let rec first x = match x with
| 1 -> 1
| x -> second (x mod 10)
and second x = first (x + 1);;
val first : int -> int = <fun>
val second : int -> int = <fun>
# first 20;;
- : int = 1
# first 12345;;
- : int = 1
Lägg märke till att den andra funktionen inte har req sökord.