2012-06-17 3 views
85

:하스켈의 예외는 어떻게 작동합니까? GHCi에서

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

왜 첫 번째 중첩 예외가 아니다?

+9

GHC에서 허용하는 변환입니다. "나는 혼자서 운영하는 컴파일러이고 모든 _ _ _s는 나에게 비슷합니다." 이 두 줄을 다르게 컴파일하도록 구현 세부 사항을 묻는 중입니까? – shachaf

+3

'error'는 특별하며 실제로 예외 메커니즘이 아닙니다. 실제로 잡을 수있는 예외는 ['Error'] (http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Error.html) 모나드를 참조하십시오. –

+1

예를 들어'(\ f g x -> f (g x)) 오류 오류 "는 그 함수가'(.)'과 동등하지만''. 아마도 Prelude가 컴파일 된 최적화 플래그와 관련이있을 수 있습니다. – shachaf

답변

99

대답은 (이 부정확 한 예외 순수 코드가 이 뛰어난 값의 설정에 평가 표시 할 수

의 (다소 놀라운) 의미라는 것이다 즉 error 또는 undefined의 가치, 그리고 명시 적으로 이 아닌 예외 종류 generated in IO)이면 언어는 해당 집합의 모든 값을 반환 할 수 있습니다. Haskell의 예외적 인 값은 명령형 언어를 기반으로 한 제어 흐름 기반의 예외가 아니라 부동 소수점 코드에서보다 비슷합니다 (NaN).

도 고급 Haskellers에 대한 가끔 잡았다는 경우 등입니다 : 코드가 예외의 집합으로 평가

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

이후, GHC는 하나를 선택 무료입니다. 최적화 기능을 켜면 항상 "그렇지 않음"으로 평가됩니다.

왜 이렇게할까요? 그렇지 않으면 우리는 언어의 평가 순서를 지나치게 제한합니다. 우리의 결정 결과를 수정해야 할 것입니다 :에 의해

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

을 예를 들어, 오류 값이있는 경우는 왼쪽에서 오른쪽으로 평가하는 것이 필요. 매우 un-Haskelly!

error을 지원하기 위해 코드에서 수행 할 수있는 최적화 작업을 방해하고 싶지 않으므로 해결 방법은 결과가 예외 값 집합 (비 정밀 예외)에서 비 결정적으로 선택되도록 지정하는 것입니다. 어떤면에서 모든 예외가 반환되고 하나가 선택됩니다.

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


참고 : A semantics for imprecise exceptions, 사이먼 페이튼 존스, 알라 스테 리드, 토니 호어, 사이먼 말로우, 퍼거스 헨더슨. Proc 프로그래밍 언어 설계 및 구현 (PLDI'99), Atlanta. (PDF)

+0

이것은 왜 GHC가 두 가지 다른 선택을 할 수 있는지에 대한 훌륭한 설명입니다. 왜 그것이이 자유를 왜 여기에서 실행하는지에 대한 설명은 무엇입니까? 이 표현은 매우 비슷해 보인다! –

+1

나는 GHC가 마주 칠 수있는 예외 중 하나를 선택하는 것을 이해합니다. 그러나 귀하의 "사례"예제에서 1의 입력에 대해 "하나가 아닌"예외가 발생할 수 없으므로 여전히 버그로 분류됩니다. – Peaker

+8

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