0Pricing
Lua Academy · บทเรียน

การประยุกต์ใช้บางส่วน

เติมอาร์กิวเมนต์ฟังก์ชันไว้ล่วงหน้า

การประยุกต์ใช้บางส่วน เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

การประยุกต์ใช้บางส่วนคืออะไร

การประยุกต์ใช้บางส่วนหมายถึงการกำหนดอาร์กิวเมนต์บางส่วนของฟังก์ชันไว้ตอนนี้ แล้วส่งอาร์กิวเมนต์ที่เหลือในภายหลัง ผลลัพธ์ที่ได้คือฟังก์ชันใหม่ที่ต้องการอาร์กิวเมนต์น้อยลง

วิธีนี้ช่วยเปลี่ยนฟังก์ชันทั่วไปให้เป็นฟังก์ชันเฉพาะทาง โดยกำหนดค่าที่คุณทราบอยู่แล้วไว้ล่วงหน้า

ตัวอย่างการเขียนด้วยตนเอง

สมมติว่าคุณมีฟังก์ชัน add คุณสามารถสร้าง addFive ได้โดยเขียนคลอเชอร์ที่เก็บค่า 5 ไว้และรอรับตัวเลขตัวที่สอง

ค่าที่เก็บไว้จะอยู่ในฟังก์ชันที่คืนค่าออกมา ดังนั้นการเรียกใช้แต่ละครั้งจึงต้องการเพียงอาร์กิวเมนต์ที่เหลือ

local function add(a, b)
  return a + b
end

local function addFive(b)
  return add(5, b)
end

print(addFive(10))
print(addFive(2))

กำหนดอาร์กิวเมนต์ตัวแรก

เราสามารถทำให้รูปแบบนี้ใช้ได้ทั่วไปมากขึ้น ตัวช่วย bind1 รับฟังก์ชันกับอาร์กิวเมนต์ตัวแรกที่กำหนดไว้ แล้วคืนฟังก์ชันใหม่ที่รอรับอาร์กิวเมนต์ตัวที่สอง

คลอเชอร์จะเก็บทั้ง f และค่าที่ล็อกไว้ จากนั้นส่งต่อทุกอย่างเมื่อถูกเรียกใช้

local function bind1(f, a)
  return function(b)
    return f(a, b)
  end
end

local function mul(x, y) return x * y end
local double = bind1(mul, 2)
print(double(7))
print(double(50))

การใช้อาร์กิวเมนต์จำนวนไม่จำกัด

หากต้องการกำหนดอาร์กิวเมนต์นำหน้าจำนวนเท่าใดก็ได้ ให้ใช้ไวยากรณ์อาร์กิวเมนต์จำนวนไม่จำกัดของ Lua ซึ่งก็คือ ... คุณจะเก็บอาร์กิวเมนต์ที่กำหนดไว้ แล้วเพิ่มอาร์กิวเมนต์ที่เหลือเมื่อมีการเรียกใช้

ฟังก์ชัน table.pack และ table.unpack ช่วยเก็บและกระจายรายการอาร์กิวเมนต์

local function partial(f, ...)
  local fixed = table.pack(...)
  return function(...)
    local rest = table.pack(...)
    local args = {}
    for i = 1, fixed.n do args[i] = fixed[i] end
    for i = 1, rest.n do args[fixed.n + i] = rest[i] end
    return f(table.unpack(args, 1, fixed.n + rest.n))
  end
end

local function add3(a, b, c) return a + b + c end
local add10 = partial(add3, 10)
print(add10(2, 3))

การกำหนดอาร์กิวเมนต์หลายตัว

เนื่องจาก partial รับอาร์กิวเมนต์จำนวนไม่แน่นอนได้ คุณจึงกำหนดอาร์กิวเมนต์ไว้ล่วงหน้าได้มากกว่าหนึ่งตัวพร้อมกัน ฟังก์ชันที่คืนค่ามาจึงต้องการเพียงอาร์กิวเมนต์ที่เหลือ

ในที่นี้กำหนดอาร์กิวเมนต์ไว้ล่วงหน้าสองตัวจากทั้งหมดสามตัว จึงเหลือฟังก์ชันที่รับอาร์กิวเมนต์เดียว

local function partial(f, ...)
  local fixed = table.pack(...)
  return function(...)
    local rest = table.pack(...)
    local args = {}
    for i = 1, fixed.n do args[i] = fixed[i] end
    for i = 1, rest.n do args[fixed.n + i] = rest[i] end
    return f(table.unpack(args, 1, fixed.n + rest.n))
  end
end

local function label(prefix, sep, value) return prefix .. sep .. value end
local tag = partial(label, "id", ":")
print(tag(42))

การใช้งานจริง

การประยุกต์ใช้ฟังก์ชันบางส่วนเหมาะอย่างยิ่งกับฟังก์ชันอรรถประโยชน์ทั่วไป กำหนดค่าการตั้งค่าไว้ครั้งเดียว แล้วนำฟังก์ชันเฉพาะทางไปใช้ซ้ำได้หลายครั้ง

ด้านล่าง ฟังก์ชัน greet ทั่วไปกลายเป็นฟังก์ชันทักทายที่กำหนดภาษาไว้ตายตัว ซึ่งต้องการเพียงชื่อ

local function greet(lang, name)
  if lang == "tr" then return "Merhaba, " .. name end
  return "Hello, " .. name
end

local function bind1(f, a) return function(b) return f(a, b) end end
local greetTr = bind1(greet, "tr")
print(greetTr("Ada"))
print(greetTr("Lin"))

การประยุกต์ใช้ฟังก์ชันบางส่วนกับการทำเคอร์รี

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

แนวคิดทั้งสองเกี่ยวข้องกันแต่แตกต่างกัน การทำเคอร์รีทำทีละตัว ส่วนการประยุกต์ใช้ฟังก์ชันบางส่วนกำหนดบางตัวไว้ทันที

local function curryAdd(a)
  return function(b)
    return function(c)
      return a + b + c
    end
  end
end

print(curryAdd(1)(2)(3))

การทำเคอร์รีให้ฟังก์ชันสองอาร์กิวเมนต์

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

วิธีนี้สร้างฟังก์ชันสร้างค่าที่รับอาร์กิวเมนต์เดียวและนำกลับมาใช้ซ้ำได้ ซึ่งอ่านเข้าใจได้ดีในสายการประมวลผลข้อมูล

local function curry2(f)
  return function(a)
    return function(b)
      return f(a, b)
    end
  end
end

local function pow(base, exp) return base ^ exp end
local cpow = curry2(pow)
print(cpow(2)(10))

คลอสเชอร์ทำให้ทำงานได้

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

เนื่องจากฟังก์ชันที่คืนค่าแต่ละตัวมีค่าที่จับเก็บไว้เป็นของตัวเอง คุณจึงสร้างรูปแบบเฉพาะทางได้หลายแบบอย่างปลอดภัย

local function bind1(f, a) return function(b) return f(a, b) end end
local function sub(x, y) return x - y end

local from100 = bind1(sub, 100)
local from10 = bind1(sub, 10)
print(from100(40))
print(from10(3))

ควรนำไปใช้เมื่อใด

ใช้การประยุกต์ใช้ฟังก์ชันบางส่วนเพื่อลดการทำซ้ำ เมื่อคุณเรียกใช้ฟังก์ชันด้วยอาร์กิวเมนต์ต้น ๆ ชุดเดิมซ้ำแล้วซ้ำอีก

นอกจากนี้ยังช่วยปรับฟังก์ชันให้เข้ากับอินเทอร์เฟซที่ต้องการอาร์กิวเมนต์น้อยลงได้ เช่น ฟังก์ชันเรียกกลับที่ส่งผ่านค่าเพียงค่าเดียว

ฟังก์ชันเรียกกลับที่กำหนดค่าไว้

การประยุกต์ใช้ฟังก์ชันบางส่วนเข้าคู่กับการแปลงและการคัดกรองได้ดี คุณสามารถเติมอาร์กิวเมนต์การกำหนดค่าไว้ล่วงหน้า เพื่อให้ฟังก์ชันเรียกกลับได้รับเพียงสมาชิกของรายการ

วิธีนี้ช่วยให้สายการประมวลผลข้อมูลสะอาดตา พร้อมทั้งยังปรับแต่งพฤติกรรมได้

local function map(t, f) local o={} for i,v in ipairs(t) do o[i]=f(v) end return o end
local function bind1(f, a) return function(b) return f(a, b) end end
local function scale(factor, x) return factor * x end

local r = map({1,2,3,4}, bind1(scale, 10))
print(table.concat(r, ", "))

ตรวจสอบอย่างรวดเร็ว

ทบทวนความแตกต่างระหว่างแนวคิดสองอย่างที่เกี่ยวข้องกัน

สรุปทบทวน

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

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

คำถามที่พบบ่อย

บทเรียน “การประยุกต์ใช้บางส่วน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การประยุกต์ใช้บางส่วน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การประยุกต์ใช้บางส่วน”

เติมอาร์กิวเมนต์ฟังก์ชันไว้ล่วงหน้า คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การประยุกต์ใช้บางส่วน” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันในฐานะค่า
  2. map, filter, reduce
  3. การประยุกต์ใช้บางส่วน
  4. การประกอบฟังก์ชัน
← กลับไปที่ Lua Academy