สวัสดีครับ วันนี้เราก็มาฝึกเขียนภาษา F# กันเหมือนเดิมนะครับ
ก่อนอื่นผมจะขอพูดเกี่ยวกับฟังก์ชันอีกหน่อยนะครับ
คราวนี้ให้เปิดตัว F# Interactive (Console) นะครับ
แล้วลองพิมพ์ลงไปว่า
let f a b = a + b;;
let g(a, b) = a + b;;
จะเห็นว่า f กับ g จะไม่เหมือนกัน
ลองมาดูที่ฟังก์ชัน f กันก่อน
val f : int -> int -> int
หมายถึง f จะรับค่า int 2 ตัว แล้วส่งค่า int กลับมา
ส่วน g
val g : int * int -> int
หมายถึง g จะรับค่า int * int ที่เป็น tuple แล้วจะส่งค่า int กลับออกมา
คราวนี้เราลองมากำหนดชนิดของค่าที่รับเข้าไปกัน
let f (a : float) (b : float) = a + b;;
val f : float -> float -> float
จะเห็นว่าผลลัพท์ (ค่าที่ฟังก์ชันส่งกลับมา) จะเปลี่ยนด้วย
คราวนี้เรากลับมาที่ Visual Studio กันนะครับ
วันนี้เราจะมาดูวิธีเขียนเงื่อนไขกัน
let a = 10
if a < 20 then
printfn "a < 20"
else
printfn "a >= 20"
วิธีเขียนจะคล้าย ๆ Object Pascal กับ VB.NET
ส่วนเครื่องหมายจะมี
= เท่ากับ
< น้อยกว่า
> มากกว่า
<> ไม่เท่ากับ
แต่ถ้ามีหลายเงื่อนไข จะใช้ && (and) กับ || (or) เป็นตัวเชื่อม และ elif จะหมายถึง else if
let a = 10
if a < 20 && a >= 0 then
printfn "0 <= a < 20"
elif a >= 20 then
printfn "a >= 20"
else
printfn "a < 0"
คราวนี้มาดูวิธีตรวจสอบค่ากันบ้าง ที่ในภาษา C/C++, C# เป็น switch case แต่ใน F# จะใช้ match with
let a = 4
match a with
| 0 -> printfn "Zero"
| 1 -> printfn "One"
| 2 | 3 -> printfn "2 or 3"
| x when a > 3 -> printfn "%i" x
| _ when a < -4 -> printfn "< -4"
| _ -> printfn "Other"
เครื่องหมาย | (pipe) จะเหมือนกับ case ในภาษา C#
| x when a > 3 หมายถึง ให้ค่าเป็น x ถ้า a > 3 หรือจะเขียนเป็น | x when x > 3 ก็ได้
| _ when a < -4
ไม่สามารถเขียนเป็น _ when _ < -4 ได้
นอกจากนี้ยังเขียนเป็น | x when x > 3 && x < 6 ได้อีกด้วย
ลองเขียนเคสอื่น ๆ ดูนะครับ
คราวนี้ลองมาดู resursive function (ฟังก์ชันเรียกตัวเอง) กันบ้าง
let rec fac n =
match n with
| _ when n < 0 -> failwith "n must >= 0"
| 0 | 1 -> 1
| _ -> n * fac(n - 1)
เราจะใช้ rec ต่อหลัง let เพื่อบอกว่า ฟังก์ชันที่จะสร้างเป็นฟังก์ชันแบบ recursive ครับ
ส่วน failwith หมายถึง ให้แสดง error ครับ ลองใส่ค่าติดลบดูก็ได้ครับ
ส่วนที่ต้องใส่วงเล็บ ตรง fac(n - 1) ก็เพราะว่า ถ้าเราเขียนเป็น n * fac n - 1 มันจะกลายเป็น n * fac(n) - 1
คราวนี้เราลองมารับค่ากันบ้างครับ
ก่อนอื่นเราต้องเรียก namespace System ขึ้นมาก่อน ด้วยคำสั่ง open เหมือนกับ using ใน C# และ Import ใน VB.NET
open System
printf "Enter a number: "
let a = int(Console.ReadLine())
printfn "%i" a
คราวนี้ถ้าจะรับข้อความเข้ามาทั้งบรรทัด
open System
printf "Enter a string: "
let a = Console.ReadLine()
printfn "%s" a
และเราจะแยกข้อความออกจากกันถ้าเจอเว้นวรรค
open System
printf "Enter a string: "
let a = Console.ReadLine().Split()
printfn "%A" a
ตอนนี้เราจะได้ a เป็น array นะครับ จึงไม่สามารถใช้ %s กับ a ได้
จากตรงนี้ลองพิมพ์ข้อความลงไปว่า Hello World
เราจะได้ [|"Hello"; "World"|]
ซึ่งเราจะเขียนแบบนี้ตอนสร้าง array ครับ
let a = [|1; 2; 3; 4|]
printfn "%A" a
สมาชิกแต่ละตัวจะใช้ ; (semi-colon) เป็นคั่น และใช้ [| |] ครอบ
แล้วถ้าต้องการรับค่าเข้ามาแล้วแปลงเป็น int หล่ะจะทำยังไง
เช่น ใส่ค่าเข้ามาว่า 1 6 12 จะให้รับเข้ามาเป็น array [|1; 6; 12|]
open System
printf "Enter a string: "
let a = Array.map(fun x -> int x) (Console.ReadLine().Split())
printfn "%A" a
เราจะใช้คำสั่ง Array.map เข้ามาช่วย แล้วเขียนฟังก์ชันข้างใน
หรือจะเขียนว่า
let a = Console.ReadLine().Split() |> Array.map(fun x -> int x)
ก็ได้
แล้วเจ้า |> (pipe + >) มันคืออะไร ?
เครื่องหมาย |> นิยามโดย
let (|>) x f = f x
ลองดูกับฟังก์ชันง่าย ๆ
open System
let a = Math.Cos 5.0
printfn "%f" a
เราจะเขียนเป็น
let a = 5.0 |> Math.Cos
ก็ได้ มีความหมายเหมือนกัน
เริ่มงงกันแล้วใช่ไหมครับ งั้นวันนี้พอแค่นี้ก่อนละกันครับ เดี๋ยวผมจะมาพูดเรื่อง Array อีกทีนะครับ