กลับไปหน้าบทความ

อ่าน 2 นาที

โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ

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

โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ

(Learn how and when to remove this message)

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

คำนิยาม

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

ตามหลักการแล้วโครงสร้างข้อมูลเชิงฟังก์ชันบริสุทธิ์คือโครงสร้างข้อมูลที่สามารถนำไปใช้ในภาษาเชิงฟังก์ชันบริสุทธิ์ได้เช่นHaskellในทางปฏิบัติ หมายความว่าโครงสร้างข้อมูลจะต้องสร้างขึ้นโดยใช้เฉพาะโครงสร้างข้อมูลแบบคงอยู่ เช่น ทูเพิลประเภทผลรวมประเภทผลคูณและประเภทพื้นฐาน เช่น จำนวนเต็ม อักขระ และสตริง โครงสร้างข้อมูลดังกล่าวจะต้องคงอยู่ อย่างไรก็ตาม โครงสร้างข้อมูลแบบคงอยู่ไม่ได้เป็นเชิงฟังก์ชันบริสุทธิ์เสมอไป[ 1 ] : 16 ตัวอย่างเช่นอาร์เรย์แบบคงอยู่เป็นโครงสร้างข้อมูลแบบคงอยู่และถูกนำไปใช้โดยใช้อาร์เรย์ ดังนั้นจึงไม่ใช่เชิงฟังก์ชันบริสุทธิ์

ในหนังสือPurely functional data structuresโอคาซากิเปรียบเทียบการอัปเดตแบบทำลายล้างกับมีดของเชฟฝีมือเยี่ยม[ 1 ] : การอัปเดตแบบทำลายล้างไม่สามารถย้อนกลับได้ ดังนั้นจึงไม่ควรใช้เว้นแต่จะแน่ใจว่าไม่ต้องการค่าก่อนหน้าอีกต่อไป อย่างไรก็ตาม การอัปเดตแบบทำลายล้างยังสามารถให้ประสิทธิภาพที่ไม่สามารถหาได้จากเทคนิคอื่น ตัวอย่างเช่น โครงสร้างข้อมูลที่ใช้อาร์เรย์และการอัปเดตแบบทำลายล้างอาจถูกแทนที่ด้วยโครงสร้างข้อมูลที่คล้ายกัน โดยที่อาร์เรย์ถูกแทนที่ด้วยแผนที่รายการเข้าถึงแบบสุ่ม หรือต้นไม้สมดุลซึ่งยอมรับการใช้งานฟังก์ชันบริสุทธิ์ แต่ต้นทุนการเข้าถึงอาจเพิ่มขึ้นจากเวลาคงที่ไปเป็นเวลาลอการิทึม

การรับรองว่าโครงสร้างข้อมูลเป็นแบบฟังก์ชันล้วนๆ

โครงสร้างข้อมูลไม่สามารถเป็นฟังก์ชันโดยเนื้อแท้ได้เสมอไป ตัวอย่างเช่น สแต็กสามารถนำไปใช้เป็นรายการเชื่อมโยงเดี่ยวได้การนำไปใช้นี้เป็นฟังก์ชันอย่างแท้จริงตราบใดที่การดำเนินการบนสแต็กเพียงอย่างเดียวจะส่งคืนสแต็กใหม่โดยไม่เปลี่ยนแปลงสแต็กเดิม อย่างไรก็ตาม หากภาษาไม่ใช่ฟังก์ชันอย่างแท้จริง ระบบรันไทม์อาจไม่สามารถรับประกันความไม่เปลี่ยนแปลงได้ เรื่องนี้แสดงให้เห็นโดย Okasaki [ 1 ] : 9–11 ซึ่งเขาแสดงให้เห็นว่าการต่อรายการเชื่อมโยงเดี่ยวสองรายการยังคงสามารถทำได้โดยใช้การตั้งค่าแบบเชิงคำสั่ง

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

การใช้โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ

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

ตัวอย่างเช่น ลองพิจารณาฟังก์ชันที่รับลิสต์ที่เปลี่ยนแปลงได้ ลบองค์ประกอบแรกออกจากลิสต์ และส่งคืนองค์ประกอบนั้น ในการเขียนโปรแกรมเชิงฟังก์ชันล้วนๆ การลบองค์ประกอบออกจากลิสต์จะสร้างลิสต์ใหม่ที่สั้นลง แต่จะไม่ปรับปรุงลิสต์เดิม ดังนั้น เพื่อให้ใช้งานได้ ฟังก์ชันเวอร์ชันเชิงฟังก์ชันล้วนๆ จึงมักจะต้องส่งคืนลิสต์ใหม่พร้อมกับองค์ประกอบที่ถูกลบออก ในกรณีทั่วไปที่สุด โปรแกรมที่แปลงด้วยวิธีนี้จะต้องส่งคืน "สถานะ" หรือ "ค่าที่เก็บไว้" ของโปรแกรมเป็นผลลัพธ์เพิ่มเติมจากการเรียกใช้ฟังก์ชันทุกครั้ง โปรแกรมดังกล่าวเรียกว่าเขียนในรูปแบบการส่งผ่านค่าที่เก็บไว้ (store-passing style )

ตัวอย่าง

ต่อไปนี้คือรายชื่อโครงสร้างข้อมูลนามธรรมที่มีการใช้งานในรูปแบบฟังก์ชันล้วนๆ:

การออกแบบและการดำเนินการ

ในหนังสือPurely Functional Data Structures ของเขา นักวิทยาศาสตร์คอมพิวเตอร์คริส โอคาซากิได้อธิบายถึงเทคนิคที่ใช้ในการออกแบบและใช้งานโครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ ซึ่งตัวอย่างย่อยๆ บางส่วนได้สรุปไว้ด้านล่างนี้

ความเกียจคร้านและการจดจำ

การประเมินแบบขี้เกียจมีความน่าสนใจเป็นพิเศษในภาษาฟังก์ชันบริสุทธิ์[ 1 ] : 31 เนื่องจากลำดับของการประเมินจะไม่เปลี่ยนแปลงผลลัพธ์ของฟังก์ชัน ดังนั้น การประเมินแบบขี้เกียจจึงกลายเป็นส่วนสำคัญของการสร้างโครงสร้างข้อมูลฟังก์ชันบริสุทธิ์โดยธรรมชาติ ช่วยให้การคำนวณเกิดขึ้นได้ก็ต่อเมื่อต้องการผลลัพธ์จริงๆ เท่านั้น ดังนั้น รหัสของโครงสร้างข้อมูลฟังก์ชันบริสุทธิ์จึงสามารถพิจารณาข้อมูลที่จะถูกใช้งานจริงและข้อมูลที่จะถูกละเลยได้โดยไม่สูญเสียประสิทธิภาพ การคำนวณที่จำเป็นมีเพียงสำหรับข้อมูลประเภทแรกเท่านั้น นั่นคือสิ่งที่จะดำเนินการจริง

หนึ่งในเครื่องมือสำคัญในการสร้างโครงสร้างข้อมูลที่มีประสิทธิภาพและทำงานได้อย่างบริสุทธิ์คือ memoization [ 1 ] : 31 เมื่อการคำนวณเสร็จสิ้น ผลลัพธ์จะถูกบันทึกไว้และไม่จำเป็นต้องดำเนินการซ้ำอีกครั้ง ซึ่งมีความสำคัญอย่างยิ่งในการใช้งานแบบ lazy; การประเมินเพิ่มเติมอาจต้องการผลลัพธ์เดียวกัน แต่เป็นไปไม่ได้ที่จะรู้ว่าการประเมินใดจะต้องการผลลัพธ์นั้นก่อน

การวิเคราะห์และการกำหนดตารางเวลาแบบตัดจำหน่าย

โครงสร้างข้อมูลบางอย่าง แม้แต่โครงสร้างที่ไม่ใช่ฟังก์ชันล้วนๆ เช่นอาร์เรย์ไดนามิกก็ยอมรับการดำเนินการที่มีประสิทธิภาพส่วนใหญ่ (เช่น เวลาคงที่สำหรับอาร์เรย์ไดนามิก) และไม่ค่อยมีประสิทธิภาพ (เช่น เวลาเชิงเส้นสำหรับอาร์เรย์ไดนามิก) จากนั้นสามารถใช้ การถัวเฉลี่ยเพื่อพิสูจน์ว่าเวลาการทำงานเฉลี่ยของการดำเนินการนั้นมีประสิทธิภาพ[ 1 ] : 39 กล่าวคือ การดำเนินการที่ไม่มีประสิทธิภาพเพียงเล็กน้อยนั้นหายากพอ และไม่เปลี่ยนแปลงวิวัฒนาการเชิงอะซิมโทติกของความซับซ้อนของเวลาเมื่อพิจารณาลำดับของการดำเนินการ

โดยทั่วไป การดำเนินการที่ไม่มีประสิทธิภาพนั้นไม่เป็นที่ยอมรับสำหรับโครงสร้างข้อมูลถาวร เนื่องจากการดำเนินการดังกล่าวอาจถูกเรียกใช้หลายครั้ง นอกจากนี้ยังไม่เป็นที่ยอมรับสำหรับระบบเรียลไทม์หรือระบบเชิงคำสั่ง ซึ่งผู้ใช้อาจต้องการให้เวลาที่ใช้ในการดำเนินการนั้นสามารถคาดเดาได้ ยิ่งไปกว่านั้น ความไม่แน่นอนนี้ยังทำให้การใช้การประมวลผลแบบขนานมี ความซับซ้อนมากขึ้น [ 1 ] : 83

เพื่อหลีกเลี่ยงปัญหาเหล่านั้น โครงสร้างข้อมูลบางอย่างอนุญาตให้เลื่อนการดำเนินการที่ไม่มีประสิทธิภาพออกไป ซึ่งเรียกว่าการจัดตารางเวลา [ 1 ] : 84 ข้อกำหนดเพียงอย่างเดียวคือการคำนวณการดำเนินการที่ไม่มีประสิทธิภาพจะต้องเสร็จสิ้นก่อนที่จะต้องการผลลัพธ์จริง ส่วนคงที่ของการดำเนินการที่ไม่มีประสิทธิภาพจะดำเนินการพร้อมกันกับการเรียกใช้การดำเนินการที่มีประสิทธิภาพถัดไป เพื่อให้การดำเนินการที่ไม่มีประสิทธิภาพเสร็จสมบูรณ์แล้วเมื่อจำเป็น และการดำเนินการแต่ละรายการยังคงมีประสิทธิภาพ

ตัวอย่าง: คิว

คิวแบบเฉลี่ย[ 1 ] : 65 [ 1 ] : 73 ประกอบด้วยรายการเชื่อมโยงเดี่ยวสองรายการ ได้แก่ รายการด้านหน้าและรายการด้านหลังที่กลับด้าน องค์ประกอบจะถูกเพิ่มเข้าไปในรายการด้านหลังและถูกลบออกจากรายการด้านหน้า ยิ่งไปกว่านั้น เมื่อใดก็ตามที่คิวด้านหน้าว่างเปล่า คิวด้านหลังจะถูกกลับด้านและกลายเป็นด้านหน้า ในขณะที่คิวด้านหลังจะว่างเปล่า ความซับซ้อนของเวลาเฉลี่ยของการดำเนินการแต่ละครั้งมีค่าคงที่ แต่ละเซลล์ของรายการจะถูกเพิ่ม กลับด้าน และลบออกอย่างมากที่สุดหนึ่งครั้ง เพื่อหลีกเลี่ยงการดำเนินการที่ไม่มีประสิทธิภาพซึ่งรายการด้านหลังถูกกลับด้าน คิวแบบเรียลไทม์จะเพิ่มข้อจำกัดว่ารายการด้านหลังมีความยาวเท่ากับรายการด้านหน้าเท่านั้น เพื่อให้แน่ใจว่ารายการด้านหน้ายังคงยาวกว่ารายการด้านหลัง รายการด้านหลังจะถูกกลับด้านและเพิ่มเข้าไปในรายการด้านหน้า เนื่องจากการดำเนินการนี้ไม่มีประสิทธิภาพ จึงไม่ได้ดำเนินการทันที แต่จะกระจายออกไปในการดำเนินการถัดไป ดังนั้น แต่ละเซลล์จะถูกคำนวณก่อนที่จะจำเป็น และรายการด้านหน้าใหม่จะถูกคำนวณทั้งหมดก่อนที่จะต้องเรียกใช้การดำเนินการที่ไม่มีประสิทธิภาพใหม่

ดูเพิ่มเติม

  • วิทยานิพนธ์เรื่อง โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆโดย คริส โอคาซากิ (ไฟล์ PDF)
  • ทำให้โครงสร้างข้อมูลคงอยู่โดย James R. Driscoll, Neil Sarnak, Daniel D. Sleator, Robert E. Tarjan (PDF)
  • รายการถาวรเต็มรูปแบบพร้อมการเชื่อมโยงแบบ Catenationโดย James R. Driscoll, Daniel D. Sleator, Robert E. Tarjan (PDF)
  • โครงสร้างข้อมูลถาวรจากหลักสูตรอัลกอริทึมขั้นสูงของ MIT OpenCourseWare
  • มีอะไรใหม่ในโครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ นับตั้งแต่สมัย Okasaki?บนเว็บไซต์Theoretical Computer Science Stack Exchange
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Purely_functional_data_structure&oldid=1317212756 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ

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

คำนิยาม

โครงสร้างข้อมูลแบบถาวร มีคุณสมบัติในการเก็บรักษาเวอร์ชันก่อนหน้าของตัวเองโดยไม่เปลี่ยนแปลง ในทางกลับกัน โครงสร้างที่ไม่ถาวร เช่น อาร์เรย์ ยอมรับ การอัปเดตแบบทำลายล้าง [ 1 ] นั่น คือ การอัปเดตที่ไม่สามารถย้อนกลับได้...

การรับรองว่าโครงสร้างข้อมูลเป็นแบบฟังก์ชันล้วนๆ

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

การใช้โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ

หนึ่งในความท้าทายหลักในการปรับโค้ดที่มีอยู่ให้ใช้โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ คือข้อเท็จจริงที่ว่าโครงสร้างข้อมูลที่เปลี่ยนแปลงได้นั้นให้ "ผลลัพธ์ที่ซ่อนอยู่" สำหรับฟังก์ชันที่ใช้มัน การเขียนฟังก์ชันเหล่านี้ใหม่ให้ใช้โครงสร้างข้อมูลเชิงฟังก์ชันล้วนๆ...