GHC 8, GHC.Stack
modülünden HasCallStack
modülünü sağlar; bu sayede işlevler istendiğinde bir yığın çerçevesinin kaydedilmesini isteyebilir. Ayrıca çağrı yığınını “donduran” withFrozenCallStack
işlevini sağlar, böylece başka kareler eklenemez.HasCallStack, withFrozenCallStack ile birlikte neden yığın çerçeveler ekliyor?
Basit senaryolarda, beklediğim gibi çalışır. Örneğin: Normalde foo
çağırdığınızda
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
[]
, bir yığın çerçevesi olsun ama withFrozenCallStack
ile sarın zaman, yok. Mükemmel. örnek sadece biraz daha karmaşık hale Ancak, bu beklediğim gibi davrandığını durdurur: dolaylama bu basit katmanı ekleyerek
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})]
, yığın çerçevesi hala eklenmiş olur, withFrozenCallStack
uygulamama rağmen. Niye ya?
Kavramsal olarak, HasCallStack
benim anlayış mevcut çağrı yığını pushCallStack
örtülü bir kullanım gibi olduğunu ve pushCallStack
donmuş bir çağrı yığını üzerinde hiçbir etkisi yoktur. O zaman neden withFrozenCallStack
yukarıdaki yığın çerçevesinin çağrı yığına eklenmesini engellemiyor?
Ahh, elbette, bu mantıklı. Haskell'deki örtük parametreler hakkındaki sezgilerim açıkça en iyisi değil, çünkü bu sadece 'HasCallStack' değil, örtük bir parametreye uygulanacaktır. Neyse, teşekkürler. –
Neredeyse, ama pek de değil. Normal bir örtük parametresiyle, kısıtlamayı kullanmayı bıraktığınız yerde açıkça bağlı değilse bir hata alırsınız. Ancak 'HasCallStack' ile derleyici bunu algılar ve ilk çağrı yığınını büyülü olarak bağlar. –
Aha, evet, bu mantıklı - yine haklısın. :) HasCallStack'in büyülü doğası kesinlikle biraz kafa karıştırıcı. Hâlâ HasCallStack'ın kısıtlamalarının nasıl sonuçlandığını incelediğimi tamamen anladığımı sanmıyorum, ama neyse ki bu benim için çok fazla sorun değil gibi görünüyor haha. –