2011/11/10

F# - #2

สวัสดีครับ วันนี้เราจะมาฝึกเขียนภาษา F# กันอีกเช่นเคย แต่จะเป็นเรื่องอะไร ลองทายดูสิครับ
...
วันนี้เราจะมาเขียนฟังก์ชันกันครับ !!!!
อ่านถูกแล้วหล่ะครับ มันคือฟังก์ชัน นั้นแหละครับ
บางคนอาจจะงง ยังไม่ทันไรก็ขึ้นฟังก์ชันแล้ว ?
จริง ๆ แล้วฟังก์ชันในภาษา F# นั้นสร้างไม่ยากเลยครับ เพราะว่าใช้คำสั่ง let เหมือนกัน

let myFun() = 5
let a = myFun()
printfn "%A" a

เหมือนกันเลยครับ แต่ต้องใส่ () ต่อท้ายเท่านั้นเอง เราก็จะได้ myFun เป็นฟังก์ชันแล้ว... เย้

ต่อไปมาลองสร้างฟังก์ชันที่มีการรับค่าเข้าไปดูครับ

let add a b = a + b
let r = add 6 4
printfn "%A" r

เป็นยังไงบ้างครับ ง่ายใช่ไหมหล่ะครับ

แล้วถ้าฟังก์ชันมีหลายบรรทัดหล่ะ จะเขียนยังไงดี ?

ก่อนอืนเลยต้องบอกว่า scope ใน F# จะใช้ย่อหน้าครับ เช่นในภาษา C/C++, C# จะเป็น { } ใน Object Pascal เป็น begin end; เป็นต้น

let f x =
    let r1 = x * x
    let r2 = r1 + 20
    r2
printfn "%A" (f 6)

จะเห็นว่าคำสั่งที่อยู่ในย่อหน้า ตั้งแต่ let r1 จนถึง r2 จะเป็นคำสั่งในฟังก์ชัน f ครับ

ลองมาดูกันทีละบรรทัดนะครับ
let f x =

หมายถึง สร้างฟังก์ชัน f ที่รับค่า x เข้าไป
    let r1 = x * x
    let r2 = r1 + 20

คือการสร้างค่าคงที่ ที่อยู่ในฟังก์ชันครับ เพราะฉะนั้นเราจึงใช้ r1 กับ r2 ได้แค่ในฟังก์ชัน f เท่านั้น

    r2

คือการส่งค่ากลับออกมาให้ฟังก์ชันครับ คล้าย ๆ กับ return r2; ในภาษา C/C++, C# ฯลฯ

นอกจากนี้เรายังสามารถประกาศค่าคงที่ ที่ชื่อซ้ำกันในฟังก์ชันได้อีกด้วย

let f x =
    let r = x * x
    let r = r + 20
    r

คำสั่งนี้จะเหมือนกับคำสั่งก่อนหน้านี้เลยครับ
จริง ๆ แล้วเราจะใส่วงเล็บตอนประกาศฟังก์ชันหรือตอนเรียใช้ก็ได้นะครับ

let f(x) =
    let r = x * x
    let r = r + 20
    r
printfn "%A" (f(6))

นอกจากนี้ยังสามารถใช้ชื่อซ้ำกันใน scope ที่ซ้อนกันได้

let f x =
    let r =
        let r = x * x
        r + 1
    r * 2
printfn "%A" (f 3)

จะเห็นว่าตำสั่ง r + 1 จะหมายถึง r ที่เป็น x * x และ r * 2 จะหมายถึง r ตัวแรกที่อยู่หลัง let f x


Tuple คืออะไร ? http://en.wikipedia.org/wiki/Tuple

ลองดูตัวอย่างกันดีกว่าครับ
let (a, b) = (1, 2) // หรือ let a, b = 1, 2
printfn "a = %A" a
printfn "b = %A" b

เราจะได้ a = 1 และ b = 2 ครับ คิดว่าดูจากตัวอย่างแล้วน่าจะเข้าใจนะครับ

คราวนี้
let a = (1, 2)
printfn "%A" a

ลองรันดูนะครับ แล้วดูว่า a คืออะไร ?

ถ้ารันดูแล้วจะรู้ว่า a จะเท่ากับ (1, 2)

แล้วจะเอาค่าออกมายังไงหล่ะ ?
let a = (1, 2)
let x = fst a
let y = snd a
printfn "x = %A\ny = %A" x y

เราจะใช้ฟังก์ชัน fst เพื่อเอาค่าของตัวแรกออกมา และใช้ snd เพื่อเอาค่าตัวหลังออกมา ซึ่งฟังก์ชันทั้ง 2 ตัวนี้มีอยู่แล้วครับ แต่ถ้าใครจะเขียนเองก็ไม่ยากครับ
let fst(a, b) = a
let snd(a, b) = b

แต่ต้องใส่วงเล็บด้วยนะครับ จะเขียนเป็น fst a b ไม่ได้ เพราะ (a, b) มันคือ tuple ไงครับ

ลองดูตัวอย่างกันอีกหน่อย
let f a b = a + b
let x = f(4, 5)
printfn "%A" x

เราไม่สามารถเขียนแบบนี้ได้นะครับ เพราะ f จะต้องรับค่าเข้าไป 2 ค่า แต่ (4, 5) มันคือ ค่าเดียวครับ
จึงต้องเขียนเป็นแบบนี้
let f(a, b) = a + b
let x = f(4, 5)
printfn "%A" x

และแน่นอนครับว่าแบบข้างล่างนี้ก็ใช้ไม่ได้
let f(a, b) = a + b
let x = f 4 5
printfn "%A" x

เพราะว่า f รับค่าเข้าไปแค่ค่าเดียว คือข้อมูลแบบ tuple (a, b) แต่ f 4 5 หมายถึง ส่ง 4 กับ 5 เข้าไปให้ f


ต่อไปมาดูการละค่ากันครับ
let a = (1, 2)
let x, _ = a
printfn "%A" x

จะได้ x = 1 ครับ เครื่องหมาย _ (underscore) หมายถึงละค่าครับ เพราะฉะนั้นเลข 2 จังไม่ถูกเก็บเข้ามา

และ _ ไม่สามารถตั้งเป็นชื่อได้ เราจึงไม่สามารถ printfn "%A" _ ได้ครับ

No comments:

Post a Comment