เอาล่ะกฎข้อแรกของการจัดการผิดพลาดใน Haskell: ไม่เคยใช้error
มันแย่มากในทุก ๆ ด้าน มันมีอยู่จริงเป็นการกระทำของประวัติศาสตร์และความจริงที่ว่าพรีลูดใช้มันแย่มาก อย่าใช้มัน
ช่วงเวลาที่เป็นไปได้เพียงอย่างเดียวที่คุณสามารถใช้งานได้ก็คือเมื่อมีบางสิ่งที่เลวร้ายมากภายในตัวเองซึ่งบางสิ่งต้องผิดไปจากสิ่งที่เป็นจริงมาก ๆ
ตอนนี้กลายเป็นคำถามVSMaybe
เหมาะอย่างยิ่งกับบางสิ่งบางอย่างเช่นซึ่งอาจหรืออาจจะไม่คืนค่า แต่มีเพียงเหตุผลเดียวที่เป็นไปได้ที่จะล้มเหลว กำลังพูดอะไรบางอย่างเช่น "มันพังและคุณรู้อยู่แล้วว่าทำไม" บางคนก็บอกว่ามันแสดงถึงฟังก์ชั่นบางส่วนEither
Maybe
head
Nothing
รูปแบบการจัดการข้อผิดพลาดที่แข็งแกร่งที่สุดคือEither
+ ข้อผิดพลาด ADT
ตัวอย่างเช่นหนึ่งในคอมไพเลอร์งานอดิเรกของฉันฉันมีสิ่งที่ชอบ
data CompilerError = ParserError ParserError
| TCError TCError
...
| ImpossibleError String
data ParserError = ParserError (Int, Int) String
data TCError = CouldntUnify Ty Ty
| MissingDefinition Name
| InfiniteType Ty
...
type ErrorM m = ExceptT CompilerError m -- from MTL
ตอนนี้ฉันกำหนดพวงของประเภทข้อผิดพลาดซ้อนพวกเขาเพื่อให้ฉันมีข้อผิดพลาดระดับบนสุดรุ่งโรจน์ นี่อาจเป็นข้อผิดพลาดจากขั้นตอนการรวบรวมใด ๆ หรือImpossibleError
ซึ่งหมายถึงข้อผิดพลาดของคอมไพเลอร์
ข้อผิดพลาดแต่ละประเภทพยายามเก็บข้อมูลให้มากที่สุดเท่าที่จะทำได้เพื่อการพิมพ์ที่สวยงามหรือการวิเคราะห์อื่น ๆ ที่สำคัญกว่านั้นโดยไม่มีสตริงฉันสามารถทดสอบว่าการเรียกใช้โปรแกรม illtyped ผ่านตัวตรวจสอบชนิดจริงสร้างข้อผิดพลาดการรวม! เมื่อมีอะไรบางอย่างString
มันหายไปตลอดกาลและข้อมูลใด ๆ ที่อยู่ในนั้นมีความทึบแสงสำหรับคอมไพเลอร์ / การทดสอบดังนั้นจึงEither String
ไม่ได้ยอดเยี่ยม
ในที่สุดฉันก็บรรจุประเภทนี้เข้าExceptT
เป็น monad Transformer ใหม่จาก MTL นี่เป็นสิ่งสำคัญEitherT
และมาพร้อมกับชุดฟังก์ชั่นที่ดีสำหรับการขว้างและรับข้อผิดพลาดอย่างบริสุทธิ์และน่าพึงพอใจ
ในที่สุดมันก็คุ้มค่าที่จะกล่าวถึงว่า Haskell มีกลไกในการรองรับการจัดการข้อยกเว้นเช่นภาษาอื่น ๆ ยกเว้นว่าจะมีข้อยกเว้นเกิดIO
ขึ้น ฉันรู้ว่าบางคนชอบที่จะใช้สิ่งเหล่านี้สำหรับIO
แอปพลิเคชันขนาดใหญ่ซึ่งทุกอย่างอาจล้มเหลวได้ แต่บ่อยครั้งที่พวกเขาไม่ชอบที่จะคิด ไม่ว่าคุณจะใช้ข้อยกเว้นที่ไม่บริสุทธิ์เหล่านี้หรือเพียงแค่ExceptT Error IO
เป็นเรื่องของรสนิยม ส่วนตัวฉันเลือกExceptT
เพราะฉันชอบที่จะได้รับการเตือนถึงโอกาสของความล้มเหลว
โดยสรุป
Maybe
- ฉันสามารถล้มเหลวในวิธีที่ชัดเจนอย่างใดอย่างหนึ่ง
Either CustomType
- ฉันสามารถล้มเหลวได้และฉันจะบอกคุณว่าเกิดอะไรขึ้น
IO
+ ข้อยกเว้น - บางครั้งฉันก็ล้มเหลว ตรวจสอบเอกสารของฉันเพื่อดูสิ่งที่ฉันโยนเมื่อฉันทำ
error
- ฉันเกลียดคุณเหมือนกัน
head
หรือlast
ดูเหมือนจะใช้error
ดังนั้นฉันจึงสงสัยว่านี่เป็นวิธีที่ดีในการทำสิ่งต่าง ๆ หรือไม่และฉันก็ขาดอะไรบางอย่างไป คำถามนี้ตอบคำถามนี้ :)