รายการอนันต์เพิ่มเติมในรูปแบบ
นี่เป็นเรื่องราวต่อจากเรื่องราวก่อนหน้าของฉันที่สามารถพบได้ "ที่นี่"
สตรีมรวม
ครั้งที่แล้ว เราสร้างสตรีมที่น่าสนใจสองสามรายการโดยใช้ stream-add
ตอนนี้ฉันอยากจะแนะนำฟังก์ชันที่หลากหลายมากขึ้นซึ่งจะช่วยให้เราสร้างสตรีมที่น่าสนใจยิ่งขึ้นได้
ฟังก์ชันนี้แทบจะเหมือนกับ stream-add
ทุกประการ ยกเว้นว่าเราสามารถส่งการดำเนินการใดๆ ไปให้ฟังก์ชันนั้นได้ ไม่ใช่แค่ +
stream-add
และ (stream-combine +)
เทียบเท่ากัน
พลังใหม่
เราสามารถสร้างสตรีมใหม่ๆ ที่สนุกสนานได้ด้วยวิธีการรวมแบบใหม่นี้ เราสร้างจำนวนธรรมชาติโดยการบวกกระแสสองกระแสเข้าด้วยกัน ดังนั้นเราจึงสามารถสร้างเลขยกกำลังของสองโดยการคูณกระแสสองกระแส
เช่นเดียวกับจำนวนธรรมชาติ สมมติว่ากระแสแห่งกำลังของสอง powsOf2
มีอยู่จริง สตรีมนี้คือ '(1 2 4 8 16 32 ...)
เมื่อเราสตรีมรวมกันคูณกับ '(2 2 2 2 2 2 ...)
เราจะได้ '(2 4 6 8 16 32 64 ...)
เหมือนเมื่อก่อน ((stream-combine *) twos powsOf2))
เป็นส่วนท้ายของรายการของเรา และเราแค่ต้องเริ่มต้นด้วย 1
กระแสอีกประการหนึ่งที่ตอนนี้เป็นเรื่องเล็กน้อยในการสร้างคือลำดับของกำลังสอง
และแฟกทอเรียล
โปรดสังเกตอีกครั้งว่าแฟคทอเรียล: '(1 2 6 24 120 720 …)
คูณธรรมชาติ: '(1 2 3 4 5 6)
เท่ากับ cdr
ของแฟกทอเรียล: '(2 6 24 120 720 5040 …)
เนื่องจากเรามี cdr
ของแฟคทอเรียลอยู่แล้ว เราจึงต้องเริ่มต้นด้วยอันแรกอย่างชัดเจนแล้วรวมทั้งสองเข้าด้วยกัน
หากยังรู้สึกสับสนอยู่เล็กน้อย ฉันขอแนะนำให้คุณดำเนินการผ่านกระบวนการพื้นฐานในที่ทำงานดังที่ฉันแสดงไว้ในโพสต์ที่แล้ว
มุ่งหน้าสู่ไพรม์ส
หนึ่งในตัวอย่างที่คลาสสิกและสง่างามที่สุดของรายการอนันต์คือการสร้างรายการของจำนวนเฉพาะ เห็นได้ชัดว่าสิ่งนี้เป็นไปไม่ได้เนื่องจากเครื่องมือเดียวของเราคือ stream-combine
ดังนั้นเรามาแนะนำฟังก์ชันสุดท้ายกัน
stream-filter
รับภาคแสดงและสตรีม จากนั้นจะลงไปตามรายการและเก็บเฉพาะรายการที่ตรงตามภาคแสดงเท่านั้น หากรายการประเมินว่าเป็นเท็จ รายการนั้นจะถูกข้ามไป เนื่องจากทั้งหมดนี้ได้รับการประเมินอย่างเกียจคร้าน stream-filter
จึงทำงานตามความต้องการ: ดำเนินการเฉพาะสิ่งที่จำเป็นสำหรับสิ่งที่เราขอเท่านั้น
การใช้งานที่เรียบง่าย
วิธีหนึ่ง (หลายวิธี) ในการสร้างเลขคี่คือการกรองเลขคู่ทั้งหมดออกจากเลขธรรมชาติ
ตะแกรงแห่ง Eratosthenes
Sieve of Eratosthenes เป็นอัลกอริธึมโบราณในการค้นหาจำนวนเฉพาะ โดยพื้นฐานแล้ว คุณจะต้องเลือกรายการจำนวนธรรมชาติที่ขึ้นต้นด้วย 2 (จำนวนเฉพาะตัวแรก) ผลคูณใดๆ ของสองตัวตามคำนิยามไม่ใช่จำนวนเฉพาะ ดังนั้นให้ลบออกจากรายการ ตอนนี้ไปยังจำนวนเฉพาะตัวถัดไปแล้วลบจำนวนทวีคูณทั้งหมดออกจากรายการ ไปเรื่อยๆ กระบวนการนี้จะลบตัวเลขทั้งหมดที่มีตัวประกอบอื่นที่ไม่ใช่ตัวเดียวออก (อ่านเพิ่มเติม) โดยปกติแล้วกระบวนการนี้จำเป็นต้องมีขอบเขตบน แต่เราพบวิธีที่จะเล่นกับอนันต์แล้ว การประเมินแบบขี้เกียจอีกครั้งหนึ่งจะช่วยประหยัดเวลาโดยการกรองเฉพาะเมื่อเราต้องการเท่านั้น
นายกรัฐมนตรีถึงอินฟินิตี้
ฟังก์ชั่นตะแกรงใช้อัลกอริทึมที่อธิบายไว้ข้างต้น โดยจะใช้องค์ประกอบแรกของสตรีมเป็นจำนวนเฉพาะ กรองปัจจัยทั้งหมดออก และทำซ้ำขั้นตอนสำหรับจำนวนเฉพาะถัดไป (เฉพาะ) การส่งผ่านกระแสของจำนวนธรรมชาติเริ่มต้นที่ 2 จะได้จำนวนเฉพาะ
เป็นเรื่องที่น่าทึ่งที่เราสามารถสร้างโครงสร้างข้อมูลที่ไม่มีที่สิ้นสุดได้อย่างมีประสิทธิภาพภายในพื้นที่หน่วยความจำที่มีจำกัด มันแสดงให้เห็นถึงพลังและความงดงามของการประเมินแบบขี้เกียจ สำหรับการใช้งานจริงของรายการเหล่านี้ ฉันจะไม่พูดถึงเรื่องนี้ แต่ฉันพบว่า "stack overflow thread" มีประเด็นที่น่าสนใจอยู่บ้าง บางภาษาเช่น Haskell มีรายการในตัวที่ไม่มีที่สิ้นสุด ดังนั้นแนวคิดนี้จึงห่างไกลจากแค่ทางทฤษฎี
เกี่ยวกับผู้เขียน
Eric Breyer เป็นนักศึกษาระดับปริญญาตรีด้านวิทยาการคอมพิวเตอร์ที่ Rice University คุณสามารถพบเขาได้ที่ "เว็บไซต์" ของเขา เช่นเดียวกับใน "GitHub" และ "LinkedIn"