2012-03-18 6 views
3

GHC는 차질없이 컴파일하지만 런타임에 비참하게 실패이 합법적 인 Haskell 코드인가?

many_a x = 
    let 
     a = 2 
    in 
     let 
      a = 2*a 
     in 
      x*a 

직관적으로,이 는해야하지 일을. 그러나 GHC는 그것을 받아 들였습니다.

+0

왜 합법적이지 않다고 생각하십니까? – Pubby

+14

그것은 합법적이지만, 당신이 생각하는 것을하지 않습니다. – augustss

+1

이런 종류의 오해는 내가 일반적으로 어디에서''~''~''를 선호하는지 이유 중 하나이다. – leftaroundabout

답변

18

예, 유효한 하스켈 코드입니다. 사실은 두 번째 let...in 표현에서 a은 실제로 입니다. 새a입니다. 동일한 이름을 가진 새로운 변수를 정의함으로써 그림자 기존 변수를 허용 할 수 있습니다. 그러나 외부 a의 값에는 영향을주지 않습니다. 그러나 일반적으로 혼란과 실수의 가능성 때문에 나쁜 스타일로 간주됩니다. GHC에 -Wall을 전달하면이를 수행하면 경고 메시지가 표시됩니다.

a2*a으로 정의했기 때문에 런타임에 "실패"하므로 런타임에 무한 루프가 발생합니다. 이것은 게으름으로 인한 것입니다. 기본적으로 (*)은 두 인수를 곱하기 전에 두 인수를 모두 평가합니다. 2을 평가하는 것은 물론 정상적으로 작동하지만 a을 평가하면 다시 동일한 프로세스를 거치게됩니다. 무한리스트 (예 : ones = 1:ones)를 허용하는 것과 동일한 것은이 코드를 무한 루프로 만듭니다.

+0

설명해 주셔서 감사합니다. –

관련 문제