article นี้ช่วยเฉลยให้ผมเข้าใจเรื่อง currying ขึ้นอีกหน่อย
(เห็นศัพท์นี้บ่อย แต่ไม่ get ว่ามันคืออะไร)
ตัวอย่างที่เขาอธิบายก็คือ
function
add_ints
ปกติเวลาเราเขียน imperative language เช่น java
add_ints
จะเขียนแบบนี้public int add_ints(int x, int y) { return x + y; }
ถ้าจะเขียนเป็น functional language (ocaml, haskell, ...)
เราต้อง declare type ก่อน
ซึ่ง type ของ add_ints เขียนได้ดังนี้
add_ints: int -> int -> int
อ่านได้ว่า add_ints รับ parameter ชนิด int 2 ตัว
แล้ว return ค่าเป็น int
จะเห็นว่ามันดูแปลกๆ เพราะในความคิดแบบ imperative ของเราแล้ว
มันควรจะเขียนแบบนี้มากกว่า
add_ints: (int , int) -> intadd_ints: (int -> int) -> int
ที่เป็นเช่นนี้เพราะ ใน Haskell (ขอยกตัวอย่างเฉพาะ haskell) มันพิสดารตรงที่ว่า
ถ้าเรา pass parameter แค่ตัวเดียวให้กับ add_ints version java
ผลก็คือ code จะ compile ไม่ผ่าน
แต่สำหรับกับพวก haskell แล้ว
การ pass parameter ตัวเดียวให้กับ add_ints
มันจะ return กลับมาเป็น function อีก function หนึ่งแทน
โดย function นั้นจะรับ parameter ที่เป็น int ตัวเดียว
และเมื่อเรา call function นั้นอีกทอด เราก็จะได้ผลบวกที่ต้องการ
ลองดูตัวอย่าง
add_ints :: int -> int -> int
add_ints x y = x + y
ลอง run ดู
Main> add_ints 1 7
8
Main> (add_ints 2) 4
6
ใครสนใจอ่าน currying ต่อได้ใน wikipedia
2 comments:
ใน ML ก็เป็นแบบนั้นเหมือนกันครับ เหมือนจะเรียกว่า partially instantiated function... เห็นครั้งแรกผมตกใจมาก
(แล้วก็เอาไปให้นักเรียนตกใจด้วยเหมือนกัน)
:)
ใช่ครับ อารมณ์เดียวกัน
เห็นแล้วตกใจ
ต้องรีบบอกคนอื่น
Post a Comment