Pola fungsi
Sejauh ini, Anda telah menggunakan ekspresi berulang dan menempatkan ekspresi tersebut dalam fungsi. Kode kini terlihat lebih baik dan lebih mudah dibaca. Saat Anda lebih terbiasa menggunakan fungsi, ada baiknya mulai melihat beberapa pola kuat yang ada di ruang ini. Dengan menggunakan pola-pola ini, Anda mendapatkan kode yang lebih mudah dibaca dan dikelola.
Deklaratif vs. imperatif
Saat Anda mulai mengkoding, kemungkinan besar Anda menulis ekspresi. Kemudian Anda menulis ekspresi lain diikuti oleh ekspresi lain, satu demi satu. Fokus Anda adalah memecahkan masalah, dan Anda bertindak spesifik tentang cara Anda menyelesaikannya. Pendekatan ini disebut sebagai pendekatan imperatif. Tidak ada yang salah dengan itu karena itu memecahkan masalah yang ada. Tapi ada rute lain yang harus diambil, yaitu adalah pendekatan deklaratif. Anda dapat melihat contoh pendekatan deklaratif saat Anda mengkueri database dengan menggunakan SQL.
Berikut adalah contoh ekspresi:
SELECT *
FROM Students s
WHERE s.Location = "Ohio"
Apa yang membuat kode ini deklaratif adalah bahwa Anda meminta apa yang Anda inginkan, tetapi Anda tidak menentukan bagaimana Anda ingin masalah diselesaikan. Anda menyerahkan cara penyelesaian kepada SQL.
Anda juga dapat menerapkan pendekatan ini ke F#. Kode berikut menggunakan pendekatan deklaratif:
let studentsFromOhio =
allStudents
|> filterLocation "Ohio"
Dalam kode sebelumnya, Anda beroperasi pada data dan meminta apa yang diinginkan tanpa spesifik tentang bagaimana Anda ingin melakukannya. Saat kode Anda terlihat seperti contoh sebelumnya, kode mudah untuk dibaca dan dialihkan. Untuk mencapai titik ini, mari kita lihat beberapa pola berguna yang didukung di F#.
Pola fungsi
Ada beberapa pola berguna dalam F# yang dapat Anda gunakan untuk mengambil pendekatan yang lebih fungsional. Kita akan membahas pola-pola berikut:
- Komposisi: Komposisi menggabungkan beberapa fungsi bersama-sama menjadi satu fungsi.
- Alur: Alur dimulai dengan nilai dan kemudian secara berurutan memanggil beberapa fungsi dengan menggunakan output dari satu fungsi sebagai input untuk fungsi berikutnya.
Komposisi
Komposisi adalah tentang menggabungkan fungsi dan menerapkannya, satu demi satu, dalam urutan tertentu. Operator komposisi mengambil dua fungsi dan mengembalikan fungsi baru.
Saat Anda menulis kode, Anda akan sering mendapati diri memanggil satu fungsi dan kemudian fungsi lain tepat setelahnya. Misalnya, Anda mungkin ingin memesan dalam daftar dan memfilter semua produk yang diskon.
Dalam contoh berikut, fungsi add2() dipanggil dan hasilnya disalurkan ke fungsi multiply3().
let add2 a = a + 2
let multiply3 a = a * 3
let addAndMultiply a =
let sum = add2 a
let product = multiply3 sum
product
printfn "%i" (addAndMultiply 2) // 12
Pola ini sangat umum sehingga F# memiliki operator untuk itu. Operator >> memungkinkan Anda menggabungkan dua fungsi atau lebih ke dalam satu fungsi yang lebih besar. Dengan menggunakan operator >>, Anda dapat menyederhanakan kode sebelumnya, seperti:
let add2 a = a + 2
let multiply3 a = a * 3
let addAndMultiply = add2 >> multiply3
printfn "%i" (addAndMultiply 2) // 12
Fungsi gabungan addAndMultiply() menerapkan fungsi yang terdiri dari kiri ke kanan. Dalam contoh ini, add2() terjadi terlebih dahulu dan multiply3() terjadi terakhir.
Pipeline
Operator alur |> mengambil fungsi dan argumen dan mengembalikan nilai. Mari kita lihat bagaimana alur berbeda dari komposisi dengan contoh ini:
let list = [4; 3; 1]
let sort (list: int list) = List.sort list
let print (list: int list)= List.iter(fun x-> printfn "item %i" x) list
list |> sort |> print // item 1 item 3 item 4
Di baris terakhir kode, Anda mulai dengan daftar bilangan bulat, list, yang berfungsi sebagai input ke fungsi pertama, sort(). Hasil dari operasi tersebut disalurkan ke dalam print(). Perbedaan utama antara alur dan komposisi adalah bahwa dengan alur, Anda memulai dengan beberapa data, yang merupakan daftar bilangan bulat dalam kasus ini, dan kemudian menuntunnya melalui serangkaian fungsi.