Haskell의 예외는 어떻게 작동합니까?


87

GHCi에서 :

Prelude> error (error "")
*** Exception: 
Prelude> (error . error) ""
*** Exception: *** Exception: 

첫 번째 예외가 중첩 된 예외가 아닌 이유는 무엇입니까?


9
이것은 GHC가 만들 수있는 변환입니다. "나는 혼자서 작동하는 컴파일러이고 모든 _ | _s는 나와 비슷합니다." 이 두 줄을 다르게 컴파일하는 구현 세부 정보를 요청하고 있습니까?
shachaf

3
error특별하고 실제로 예외 메커니즘이 아닙니다. 실제 포착 가능한 예외에 대해서는 Error모나드를 참조하십시오 .
Cat Plus Plus

1
예를 들어 해당 함수가와 동일 (\f g x -> f (g x)) error error ""하더라도과 다르게 작동 (.) error error ""합니다 (.). Prelude가 컴파일 된 최적화 플래그와 관련이있을 수 있습니다.
shachaf

5
또한 iterate error "" !! n굉장 fix error합니다.
Vitus

9
나는 항상 그런 척하고 error = error그에 따라 프로그램합니다.
Gabriel Gonzalez

답변:


102

대답은 이것이 부정확 한 예외 의 (다소 놀라운) 의미라는 것입니다.

순수 코드 가 예외적 인 값 집합 (즉, error또는 값 undefined, IO에서 생성 된 예외 유형이 명시 적으로 아님) 으로 평가되는 것으로 표시 될 수있는 경우 언어는 해당 집합의 모든 값이 반환되도록 허용합니다. Haskell의 예외적 인 값은 명령형 언어의 제어 흐름 기반 예외보다는 부동 소수점 코드 와 비슷 합니다.NaN

고급 Haskeller에게도 가끔씩 문제가 발생하는 경우는 다음과 같습니다.

 case x of
   1 -> error "One"
   _ -> error "Not one"

코드가 일련의 예외로 평가되기 때문에 GHC는 자유롭게 선택할 수 있습니다. 최적화를 사용하면 항상 "하나가 아님"으로 평가됩니다.

우리는 왜 이것을합니까? 그렇지 않으면 언어의 평가 순서를 과도하게 제한 할 수 있습니다. 예를 들어 다음에 대한 결정 론적 결과를 수정해야합니다.

 f (error "a") (error "b")

예를 들어 오류 값이있는 경우 왼쪽에서 오른쪽으로 평가하도록 요구합니다. 매우 해스켈 리!

을 (를) 지원하기 위해 코드에서 수행 할 수있는 최적화를 손상시키고 싶지 않기 때문에 error해결책은 결과가 예외적 값 집합에서 비 결정적 선택 인 부정확 한 예외임을 지정하는 것입니다. 어떤 방식 으로든 모든 예외가 반환되고 하나가 선택됩니다.

일반적으로 예외는 예외입니다. 예외는 예외입니다. 예외 내부의 문자열에 신경 쓰지 않는 한 일반적으로 error디버그에 사용 하는 것이 매우 혼란 스럽습니다.


참고 문헌 : 부정확 한 예외에 대한 의미론 , Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson. Proc Programming Languages ​​Design and Implementation (PLDI'99), Atlanta. ( PDF )


2
나는 GHC가 발생할 수있는 예외 중 하나를 선택하는 것을 이해합니다. 그러나 "사례"예제에서 입력 1에 대해 "Not one"예외가 발생할 수 없으므로 여전히 버그로 분류합니다.
Peaker 2012-06-17

8
@Peaker dead code elim-옵티마이 저는 오류가 결과인지 확인하기 위해 x를 볼 필요가 없으며 모든 분기가 "동일한"값을 생성하므로 입력 값을 완전히 무시할 수 있습니다. 부정확 한 예외 상황에서 버그가 아닙니다!
Don Stewart

1
@lpsmith : 모든 예외 유형이 정확하지 않다고 생각합니다 (를 사용하여 던져 질 때 throw). 그리고 throwIO.
FunctorSalad

4
@Peaker 나는 당신이 옳다고 생각합니다. 부정확 한 예외 문서에 제시된 규칙을 따르고 싶다면 ghc가이 표현을 최적화해야한다고 생각하지 않습니다.
augustss

3
부정확 한 예외 문서 말하는 것처럼 보이는 것은 케이스 스크 러틴 이 오류 값이면 분기의 오류 값이 반환 될 수 있다는 것입니다. 그래서 case error "banana" of (x:xs) -> error "bonobo"당신에게 줄 수 있습니다 * Exception: bonobo.
Ben Millwood 2013 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.