ดังนั้นการสอบถามฐานข้อมูลหรือการเขียนไฟล์จึงไม่สามารถทำได้ในลักษณะการทำงานที่บริสุทธิ์ตามคำจำกัดความ ตัวอย่างเช่นนั่นเป็นหนึ่งในเหตุผลที่เราต้องการพระ
ไม่มีใคร "ต้องการ" พระนั่นเป็นวิธีเดียวที่จะอธิบายสิ่งต่าง ๆ ในความเป็นจริงมันอาจไม่ใช่วิธีที่ดีที่สุด บางรูปแบบของการพิมพ์ผล , ประเภทเอกลักษณ์หรือระบบที่อยู่บนพื้นฐานเต็มตรรกะเชิงเส้นดูเหมือนโน้มน้าวใจมากในทางทฤษฎี แต่ทุกขาออกที่รุนแรงมากขึ้นจากระบบการพิมพ์ที่รู้จักกันดีและมีความซับซ้อนมากขึ้นในการแสดง Monadic IO ที่พบใน Haskell เป็นการประนีประนอมระหว่างการใช้งานและความเรียบง่ายเนื่องจากมันเป็นรูปแบบการเขียนโปรแกรมที่จำเป็นอย่างสมบูรณ์ในลักษณะที่สามารถอยู่ร่วมกับระบบประเภท ML ที่มีอยู่แล้วซึ่งใช้ในภาษาได้
คำถามคือ - ทำไมเราถึงถือว่า STDOUT เป็นสิ่งที่ไม่บริสุทธิ์? ใช่ filehandler มีความเสี่ยง - เราไม่สามารถมั่นใจได้ว่าข้อมูลจะถูกเขียนเสมอ แต่แล้ว STDOUT ล่ะ? ทำไมเราควรคิดว่ามันเป็นสิ่งที่ไม่น่าเชื่อถือ? การประเมินตนเองนั้นไม่น่าเชื่อถือมากขึ้นหรือไม่ ฉันหมายความว่าเราสามารถดึงทริกเกอร์ได้ตลอดเวลาและทำให้การคำนวณขัดจังหวะ
มันไม่ได้และเราทำไม่ได้ อินพุทและเอาท์พุทจากโปรแกรมโดยรวมถือได้ว่าเป็นข้อโต้แย้งและผลลัพธ์จากการรักษาโปรแกรมทั้งหมดให้เป็นฟังก์ชั่นบริสุทธิ์ขนาดใหญ่ ตราบใดที่มันพิมพ์สิ่งเดียวกันเพื่อ stdout ถ้าคุณให้อาหารสิ่งเดียวกันจาก stdin มันยังคงเป็นฟังก์ชั่นที่บริสุทธิ์ ในความเป็นจริงก่อนที่จะแนะนำ monadic IO Haskell ใช้ระบบ I / O แบบสตรีมที่ใช้ลำธารสันหลังยาวที่บริสุทธิ์สำหรับอินพุตและเอาต์พุต มันลดลงเพราะเห็นได้ชัดว่าเป็นความเจ็บปวดที่จะใช้ซึ่งอาจทำให้คุณมีความคิดว่าทำไมคุณไม่เคยได้ยินอะไรแบบนี้ :]
หากต้องการให้ประเด็นเป็นไปอย่างราบรื่นให้ลองใช้ภาษาลึกลับที่เรียบง่ายLazy K :
Lazy K เป็นภาษาโปรแกรมการทำงานที่โปร่งใสซึ่งอ้างอิงได้ซึ่งเก็บรวบรวมขยะด้วยระบบ I / O แบบสตรีมที่ใช้งานง่าย
สิ่งที่ทำให้ Lazy K แตกต่างจากภาษาอื่น ๆ คือการขาดคุณสมบัติอื่นเกือบทั้งหมด ยกตัวอย่างเช่นมันไม่ได้นำเสนอระบบประเภท polymorphic แบบ Hindley-Milner มันไม่ได้จัดส่งมาพร้อมกับไลบรารีมาตรฐานขนาดใหญ่ที่รองรับการเขียนโปรแกรม GUI ที่ไม่ขึ้นกับแพลตฟอร์มและการเชื่อมโยงกับภาษาอื่น Lazy K ไม่ได้ให้วิธีการใด ๆ ในการกำหนดหรืออ้างถึงฟังก์ชั่นอื่น ๆ นอกเหนือจากบิวด์อิน การไร้ความสามารถนี้เสริมด้วยการขาดการสนับสนุนสำหรับตัวเลขสตริงหรือชนิดข้อมูลอื่น ๆ อย่างไรก็ตาม Lazy K นั้นก็ยังสมบูรณ์อยู่
( ... )
โปรแกรม Lazy K อาศัยอยู่ใน Platonic realm ที่เป็นอมตะเช่นเดียวกับฟังก์ชั่นทางคณิตศาสตร์สิ่งที่หน้า Unlambda เรียกว่า "อาณาจักรแห่งความสุขของแคลคูลัสแลมบ์ดาที่บริสุทธิ์ เช่นเดียวกับการรวบรวมขยะซ่อนกระบวนการการจัดการหน่วยความจำจากโปรแกรมเมอร์ดังนั้นความโปร่งใสในการอ้างอิงจึงซ่อนกระบวนการประเมินผล ความจริงที่ว่าการคำนวณบางอย่างมีความจำเป็นเพื่อที่จะดูรูปภาพของชุด Mandelbrot หรือเพื่อที่จะ "รัน" โปรแกรม Lazy K นั้นเป็นรายละเอียดการใช้งาน นั่นคือสาระสำคัญของการเขียนโปรแกรมฟังก์ชั่น
( ... )
วิธีจัดการอินพุตและเอาต์พุตในภาษาที่ไม่มีผลข้างเคียง? ในแง่หนึ่งอินพุตและเอาต์พุตไม่ใช่ผลข้างเคียง พวกมันคือเพื่อพูดด้านหน้าและเอฟเฟกต์กลับ ดังนั้นมันจึงอยู่ใน Lazy K ซึ่งโปรแกรมนั้นได้รับการปฏิบัติเสมือนเป็นฟังก์ชันจากพื้นที่ของอินพุตที่เป็นไปได้จนถึงพื้นที่ของเอาต์พุตที่เป็นไปได้
ฉันสงสัยว่าคุณจะพบภาษาที่ใช้งานได้ดีกว่านั้น!
โปรดจำไว้ว่าข้างต้นใช้เฉพาะกับการรับอินพุตและเอาต์พุตของฟังก์ชันบริสุทธิ์เท่านั้นและเชื่อมต่อกับ stdin / stdout "ภายนอก" ในบางวิธี มีความแตกต่างอย่างมากระหว่างสิ่งนั้นกับการเข้าถึงดั้งเดิม I / O ดั้งเดิมระดับระบบ รายละเอียดการนำไปใช้ของการอ่านและการเขียนไปยังสตรีมอาจทำให้สิ่งเจือปนรั่วไหลเว้นแต่จะได้รับการห่อหุ้มอย่างระมัดระวัง
ฉันคาดหวังว่านี่คือเหตุผลหลักที่คุณไม่สามารถทำสิ่งนี้โดยตรงใน Haskell - กรณีการใช้งานที่ชาญฉลาดนั้นมีขนาดเล็กกว่าเมื่อเทียบกับการใช้ monadic IO และสำหรับผู้ใช้หลังนี้มีประโยชน์มากมายในการเข้าถึงของจริง ฉันเชื่อว่านั่นเป็นสาเหตุที่ตัวอย่างเช่นอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรมไม่ได้ถูกส่งผ่านเป็นอาร์กิวเมนต์main
ถึงแม้ว่ามันจะดูเหมือนว่ามันควรจะเป็น
คุณสามารถกู้คืนรุ่นที่น้อยที่สุดของบางสิ่งบางอย่างเช่นนี้ในโปรแกรมเฉพาะแม้ว่า - เพียงแค่จับข้อโต้แย้งเป็นค่าที่บริสุทธิ์และจากนั้นใช้ฟังก์ชั่นสำหรับส่วนที่เหลือของโปรแกรมของคุณinteract