Tamam, Haskell'de ilk hata işleme kuralı: Hiçbir zaman kullanmayınerror
.
Her şekilde sadece korkunç. Tamamen bir tarih eylemi olarak var olur ve Prelude'un onu kullanması çok korkunç. Kullanmayın.
Kullanabileceğiniz akla gelebilecek tek zaman, bir şeyin içsel olarak korkunç olduğu ve gerçekliğin dokusunda bir şeylerin yanlış olması gerektiği, dolayısıyla programınızın sonucunu ortaya çıkarması gerektiğidir.
Şimdi soru Maybe
vs olur Either
. bir değere dönüşebilecek ya da vermeyecek bir Maybe
şey için çok uygundur head
, ancak başarısız olmanın tek bir nedeni vardır. Nothing
"kırdı ve nedenini zaten biliyorsun" gibi bir şey söylüyor. Bazıları kısmi bir işlevi gösterdiğini söyleyebilirdi.
En sağlam hata işleme biçimi Either
+ bir hata ADT'sidir.
Mesela hobi derleyicilerimden birinde gibi bir şeyim var
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
Şimdi bir grup hata türünü tanımlayıp iç içe geçiririm, böylece görkemli bir üst düzey hatam olur. Bu derleme herhangi bir aşamasında bir hata veya ImpossibleError
bir derleyici hata belirten bir olabilir.
Bu hata türlerinin her biri, güzel baskı veya diğer analizler için mümkün olduğunca çok bilgi tutmaya çalışır. Daha da önemlisi, bir dize sahibi olmadan, yazım denetleyicisiyle yazılmamış bir program çalıştırmanın aslında bir birleştirme hatası oluşturduğunu test edebilirim! Bir şey bir kez String
olursa, sonsuza dek gider ve içerdiği herhangi bir bilgi derleyiciye / testlere opaktır, bu yüzden de Either String
pek iyi değildir.
Sonunda bu türü ExceptT
MTL'den yeni bir monad transformatörü olarak paketledim. Bu esasen EitherT
hataların saf ve hoş bir şekilde atılması ve yakalanması için güzel bir fonksiyon dizisiyle birlikte gelir.
Son olarak, Haskell'in, içinde bir istisna yakalamak dışında, diğer diller gibi istisnaları ele alma mekanizmalarına sahip olduğunu belirtmekte fayda var IO
. Bazı insanların bunları IO
her şeyin potansiyel olarak başarısız olabileceği ağır uygulamalar için kullanmaktan hoşlandıklarını biliyorum , ancak çok nadiren bunun hakkında düşünmekten hoşlanmıyorlar. Bu saf istisnaları mı yoksa sadece ExceptT Error IO
bir zevk meselesi mi kullandığınız . Şahsen tercih ediyorum ExceptT
çünkü başarısızlık şansını hatırlatmak hoşuma gidiyor.
Özet olarak,
Maybe
- Belli bir şekilde başarısız olabilirim
Either CustomType
- Başarısız olabilirim ve sana ne olduğunu anlatacağım.
IO
+ istisnalar - Bazen başarısız oluyorum. Ne zaman fırlattığımı görmek için doktorlarımı kontrol et
error
- Ben de senden nefret ediyorum kullanıcı
head
veyalast
kullandığı göründüğü gerçeğine dayanarak ikinci kez tahminerror
ediyordum, bu yüzden bunun aslında bir şeyleri yapmanın iyi bir yolu olup olmadığını merak ediyordum ve sadece bir şeyleri özlüyorum. Bu soruya cevap veriyor. :)