2016-11-28 1 views
7

GHC 8은 GHC.Stack 모듈에서 HasCallStack을 제공합니다.이 기능을 사용하면 함수가 호출 될 때 스택 프레임을 기록하도록 요청할 수 있습니다. 또한 withFrozenCallStack 함수를 제공합니다.이 함수는 더 이상 프레임을 추가 할 수 없도록 호출 스택을 "고정"합니다.withFrozenCallStack을 사용할 때 HasCallStack이 스택 프레임을 추가하는 이유는 무엇입니까?

간단한 시나리오에서 예상대로 작동합니다. 예를 들면 : 나는 일반적으로 foo를 호출 할 때

ghci> let foo :: HasCallStack => CallStack 
      foo = callStack 
ghci> foo 
[("foo",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci2", srcLocFile = "<interactive>", srcLocStartLine = 8, srcLocStartCol = 1, srcLocEndLine = 8, srcLocEndCol = 4})] 
ghci> withFrozenCallStack foo 
[] 

, 나는 스택 프레임을 얻을,하지만 난 withFrozenCallStack로 포장 할 때, 나는하지 않습니다. 완전한. 이 예는 약간 더 복잡해진다 그러나, 내가 기대처럼 행동을 중지 : 간접 간단한 레이어를 추가하여

ghci> let foo :: CallStack 
      foo = bar 
      bar :: HasCallStack => CallStack 
      bar = callStack 
ghci> foo 
[("bar",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci9", srcLocFile = "<interactive>", srcLocStartLine = 24, srcLocStartCol = 11, srcLocEndLine = 24, srcLocEndCol = 14})] 
ghci> withFrozenCallStack foo 
[("bar",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci9", srcLocFile = "<interactive>", srcLocStartLine = 24, srcLocStartCol = 11, srcLocEndLine = 24, srcLocEndCol = 14})] 

는, 스택 프레임이 여전히 포함됩니다, withFrozenCallStack 내 사용에도 불구하고. 왜?

개념적으로, HasCallStack을 이해하면 현재 호출 스택에서 pushCallStack을 암시 적으로 사용하는 것과 같고 pushCallStack은 고정 콜 스택에 영향을주지 않습니다. 그렇다면 withFrozenCallStack은 위의 스택 프레임이 호출 스택에 추가되는 것을 방지하지 못합니까?

답변

2

코드에서 foo은 유형이 CallStack 인 정적 값입니다. 그것은 이 아니고HasCallStack 제약이 있습니다.

foo을 어떻게 그리고 어디에서 사용하든 관계없이 항상이 특정 CallStack을 참조합니다. foo 자체가 기계를 사용하는 bar을 사용하여 정의 된 것은 중요하지 않습니다. 단지 정적으로 foo = [("bar",…을 정의 할 수 있습니다.

HasCallStack => ~ foo의 서명을 추가하십시오. 이제 당신이 기대하는대로 행동합니까?

+0

아 물론 그렇습니다. 하스켈에서 내재적 인 매개 변수에 대한 나의 직감은 분명히 최선이 아니다. 왜냐하면 이것이 단지'HasCallStack'이 아닌 암묵적인 매개 변수에 적용될 것이기 때문이다. 아무튼 감사 해요. –

+0

거의 비슷하지만 아주. 일반 암시 적 매개 변수를 사용하면 제약 조건을 사용하지 않고 명시 적으로 바인딩되지 않은 경우 오류가 발생합니다. 그러나 HasCallStack을 사용하면 컴파일러가이를 감지하고 마술처럼 초기 호출 스택을 바인딩합니다. –

+0

아하, 네, 그 말이 맞습니다 - 당신이 다시 옳아 요. :)'HasCallStack'의 불가사의 한 성질은 확실히 조금 혼란 스럽습니다. 나는 아직도 'HasCallStack' 제약 조건이 유추되는 방식을 완전히 이해하고 있다고 생각하지 않지만, 다행스럽게도 그것은 실제로 나에게별로 중요하지 않은 것처럼 보인다. –

관련 문제