하스켈의 첫 번째 오류 처리 규칙 : 사용하지 마십시오error
.
그것은 모든면에서 끔찍합니다. 그것은 순수한 역사의 행위로 존재하며 Prelude가 그것을 사용한다는 사실은 끔찍합니다. 사용하지 마십시오.
당신이 그것을 사용할 수있는 유일한 시간은 무언가가 내부적으로 끔찍한 것이므로 무언가가 현실의 구조에 잘못되어 프로그램의 결과를 무질서하게 만드는 것입니다.
이제 질문은 Maybe
vs가 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
컴파일러 버그를 나타내는입니다.
이러한 각 오류 유형은 예쁜 인쇄 또는 기타 분석을 위해 가능한 한 많은 정보를 유지하려고합니다. 더 중요한 것은 문자열이 없기 때문에 형식 검사기를 통해 잘못된 형식의 프로그램을 실행하면 실제로 통일 오류가 발생하는지 테스트 할 수 있습니다! 일단 무언가가 있으면 String
영원히 사라지고 포함 된 모든 정보는 컴파일러 / 테스트에 불투명하므로 Either String
그다지 좋지 않습니다.
마지막으로이 유형을 ExceptT
MTL의 새로운 모나드 변압기에 넣습니다 . 이것은 본질적 EitherT
으로 순수하고 즐거운 방법으로 오류를 던지고 잡을 수있는 멋진 기능 모음과 함께 제공됩니다.
마지막으로, Haskell은 예외를 잡는 것이 예외라는 것을 제외하고 다른 언어와 마찬가지로 예외를 처리 할 수있는 메커니즘을 가지고 있다고 언급 할 가치가 있습니다 IO
. 어떤 사람들 IO
은 잠재적으로 모든 것이 실패 할 수있는 무거운 응용 프로그램에 이것을 사용하기를 좋아 하지만 가끔은 그것에 대해 생각하고 싶지 않습니다. 이러한 불규칙한 예외를 사용하든 아니면 ExceptT Error IO
실제로는 맛의 문제입니다. 개인적으로 나는 ExceptT
실패의 기회를 생각 나게 하기 때문에 선택합니다 .
요약하면
Maybe
-한 가지 확실한 방법으로 실패 할 수 있습니다
Either CustomType
-실패 할 수 있고 무슨 일이 있었는지 말해 줄게
IO
+ 예외-때때로 실패합니다. 내가 할 때 던지는 것을 보려면 내 문서를 확인하십시오.
error
-나도 너 싫어
head
또는last
사용하는 것처럼 보이는 사실에 근거하여 나 자신을 두 번 추측했다error
. 이것은 그 질문에 대한 답입니다. :)