cv.cm

Pemrograman · Bahasa pemrograman

Tutorial F# untuk pemula

6 menit baca

Jawaban singkat

F# adalah bahasa .NET bertipe statis yang mengutamakan gaya fungsional. F# menyimpulkan sebagian besar tipe untuk Anda, memakai indentasi alih-alih kurung kurawal, dan menjadikan data immutable, pattern matching, serta operator pipeline |> sebagai cara normal menulis kode, sambil tetap memberi akses penuh ke library .NET. Pasang .NET SDK dan jalankan script dengan dotnet fsi hello.fsx.

Apa itu F# dan siapa yang memakainya

F# dirancang oleh Don Syme di Microsoft Research dan kini merupakan bahasa open source yang dipelihara oleh Microsoft dan komunitas F# Software Foundation. F# termasuk keluarga bahasa ML (seperti OCaml) dan berjalan di .NET pada Windows, macOS, dan Linux.

Tim memakai F# untuk pemodelan keuangan, analisis data, logika bisnis yang kaya domain, back end web, dan scripting. Karena dikompilasi ke intermediate language .NET yang sama dengan C#, proyek F# dapat memakai paket NuGet apa pun dan dapat dipanggil dari kode C#.

Memasang F# dan menjalankan Hello, world

Pasang .NET SDK dari Microsoft. F# sudah disertakan, jadi tidak perlu instalasi terpisah. Untuk percobaan cepat, tulis file script dengan ekstensi .fsx dan jalankan dengan F# Interactive (dotnet fsi).

// hello.fsx
printfn "Hello, world!"
dotnet fsi hello.fsx
# Hello, world!
dotnet new console -lang "F#" -o HelloApp
cd HelloApp
dotnet run

Kelompok perintah kedua membuat proyek console lengkap dengan file .fsproj dan Program.fs. Dalam proyek, urutan file yang terdaftar di .fsproj penting: sebuah file hanya dapat memakai kode dari file di atasnya.

Nilai dan tipe dasar

let mengikat sebuah nama ke nilai. Binding bersifat immutable kecuali Anda menandainya mutable, lalu Anda mengubahnya dengan <-, bukan =.

TipeContohCatatan
int42Integer 32-bit
float3.14Floating point 64-bit (double .NET)
decimal19.99mDesimal eksak, cocok untuk uang
string"hello"String .NET yang immutable
char'a'Satu karakter
booltrue, falseNilai logika
unit()"Tanpa nilai", seperti void
let name = "Ana"
let age = 30
let mutable count = 0
count <- count + 1
printfn "%s is %d, count = %d" name age count
// Ana is 30, count = 1
let total = float age + 0.5   // explicit conversion needed

F# tidak pernah mengonversi angka secara implisit: 1 + 2.0 adalah compile error. Konversikan dengan fungsi seperti float, int, dan string.

Alur kontrol dan fungsi

if adalah ekspresi yang mengembalikan nilai, jadi kedua cabang harus bertipe sama. Perulangan ada (for, while), tetapi sebagian besar kode memakai fungsi koleksi.

let sign n =
    if n > 0 then "positive"
    elif n < 0 then "negative"
    else "zero"
for i in 1 .. 3 do
    printfn "%d squared is %d" i (i * i)
let add x y = x + y          // int -> int -> int
let add5 = add 5             // partial application
printfn "%d" (add5 10)       // 15
let square = fun x -> x * x
[1; 2; 3; 4]
|> List.filter (fun x -> x % 2 = 0)
|> List.map square
|> printfn "%A"              // [4; 16]

Argumen dipisahkan spasi, bukan koma. Setiap fungsi menerima satu argumen setiap kali (currying), jadi add 5 mengembalikan fungsi baru. Operator pipeline x |> f berarti f x dan memungkinkan Anda menulis transformasi data dari atas ke bawah. Indentasi bermakna: isi sebuah fungsi atau perulangan harus menjorok di bawahnya.

Koleksi, record, dan option

KoleksiLiteralCatatan
List[1; 2; 3]Linked list immutable, pilihan default
Array[| 1; 2; 3 |]Ukuran tetap, elemen mutable, pengindeksan cepat
Sequenceseq { 1 .. 10 }Lazy, dihitung sesuai kebutuhan
MapMap ["a", 1; "b", 2]Dictionary immutable
Setset [1; 2; 2]Set immutable berisi nilai unik
type Person = { Name: string; Age: int }
let ana = { Name = "Ana"; Age = 30 }
let older = { ana with Age = 31 }       // copy with one change
let people = [ ana; { Name = "Ben"; Age = 17 } ]
let adult = people |> List.tryFind (fun p -> p.Age >= 18)
match adult with
| Some p -> printfn "First adult: %s" p.Name
| None -> printfn "No adults"
// First adult: Ana

Record adalah tipe immutable dengan field bernama dan kesamaan struktural. F# tidak punya null untuk tipenya sendiri; nilai yang hilang berupa Option: Some value atau None. Fungsi seperti List.tryFind mengembalikan option, dan compiler memaksa Anda menangani kedua kasus.

Fitur khas: discriminated union dan pattern matching

Discriminated union menggambarkan nilai yang tepat salah satu dari beberapa case bernama, masing-masing dengan datanya sendiri. match memeriksa case-nya, dan compiler memberi peringatan jika Anda melewatkan satu.

type Shape =
    | Circle of radius: float
    | Rectangle of width: float * height: float
let area shape =
    match shape with
    | Circle r -> System.Math.PI * r * r
    | Rectangle (w, h) -> w * h
[ Circle 1.0; Rectangle (2.0, 3.0) ]
|> List.map area
|> List.iter (printfn "%.2f")
// 3.14
// 6.00

Fitur terkenal lainnya adalah inferensi tipe (Anda jarang menulis anotasi tipe), units of measure (float<m> tidak dapat dijumlahkan dengan float<s>), dan computation expression seperti task { ... } dan async { ... } untuk kode asinkron.

Penanganan error

Untuk kegagalan yang sudah diperkirakan, F# yang idiomatis mengembalikan Result: Ok value atau Error info. Untuk kegagalan tak terduga, exception .NET tersedia lewat try ... with, failwith, dan raise.

let parseAge (s: string) =
    match System.Int32.TryParse(s) with
    | true, n when n >= 0 -> Ok n
    | true, _ -> Error "Age must not be negative"
    | false, _ -> Error "Not a number"
match parseAge "abc" with
| Ok n -> printfn "Age %d" n
| Error msg -> printfn "Error: %s" msg
// Error: Not a number
let safeDivide a b =
    try Some (a / b)
    with :? System.DivideByZeroException -> None
printfn "%A" (safeDivide 10 0)   // None

TryParse punya parameter out di .NET; F# mengubahnya menjadi tuple (success, value) yang dapat langsung Anda match.

Program lengkap kecil: frekuensi kata

let text = "the cat and the hat and the bat"
text.Split(' ')
|> Array.countBy id
|> Array.sortByDescending snd
|> Array.truncate 2
|> Array.iter (fun (word, n) -> printfn "%s %d" word n)
// the 3
// and 2

Array.countBy id mengelompokkan kata yang sama dan mengembalikan pasangan (word, count), snd mengambil elemen kedua dari setiap pasangan untuk pengurutan, dan hasilnya dicetak dengan lambda yang membongkar tuple.

Langkah selanjutnya

  • Microsoft Learn: dokumentasi F#, termasuk "Tour of F#" dan referensi bahasa.
  • Berlatihlah di dotnet fsi, tempat Anda dapat menempelkan kode dan langsung melihat hasilnya; akhiri input dengan ;;.
  • Pelajari modul List, Array, Seq, Option, dan Result; sebagian besar kode sehari-hari dibangun dari modul-modul itu.
  • Lihat framework dan library web F# di NuGet setelah dasar-dasarnya nyaman.

FAQ

Apakah F# hanya untuk Windows?

Tidak. F# berjalan di .NET yang lintas platform, jadi Anda dapat membangun dan menjalankan program F# di Windows, macOS, dan Linux.

Apa perbedaan F# dan C#?

Keduanya berjalan di .NET dan dapat memakai library yang sama. C# mengutamakan berorientasi objek dengan fitur fungsional yang ditambahkan, sedangkan F# mengutamakan fungsional, dengan data immutable, inferensi tipe, dan pattern matching sebagai default.

Apa arti |> di F#?

x |> f adalah operator pipeline dan berarti f x. Operator ini meneruskan nilai di kiri sebagai argumen terakhir fungsi di kanan, sehingga rangkaian transformasi terbaca dari atas ke bawah.

Apakah F# berkaitan dengan OCaml?

Ya. F# termasuk keluarga ML dan sintaks intinya dekat dengan OCaml, tetapi dibangun untuk .NET, memakai indentasi bermakna secara default, dan punya fitur sendiri seperti computation expression.

Semua tutorial pemrograman