2013-05-27 5 views
8

क्या फ़ंक्शन के परिणाम ज्ञात होने पर जीएचसीआई डीबगर को रोकना संभव है? अबमध्यवर्ती परिणामों को खोजने के लिए जीएचसीआई ब्रेकपॉइंट डीबगर का उपयोग करें?

blabla :: [Int] -> Int 
bla  :: Int -> Int 
papperlap :: Int -> Int -> Int 

bla x   = x+x 
papperlap y x = ((y *) . bla) x 
blabla xs  = foldl papperlap 0 x 

, मैं 'papperlap' और 'bla' के परिणाम देखने के लिए करना चाहते हैं:

उदाहरण के लिए, निम्नलिखित स्निपेट पर विचार करें। लेकिन याद रखें कि जब परिणाम का मूल्यांकन किया जाता है तो मैं रुकना चाहता हूं। इसलिए 'बल' का उपयोग प्रश्न से बाहर है क्योंकि यह मूल्यांकन के क्रम को बदलता है।

जब मैं 'ब्रेक' का उपयोग करता हूं तो डीबगर बंद हो जाता है लेकिन _result का अभी तक मूल्यांकन नहीं किया गया है। कृपया मेरे GHCi सत्र नीचे खोजने के लिए है, जो वांछित मध्यवर्ती परिणाम नहीं करता है:

GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
[1 of 1] Compiling Main    (bla1.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> :break blabla 
Breakpoint 0 activated at bla1.hs:7:1-36 
*Main> :break papperlap 
Breakpoint 1 activated at bla1.hs:6:1-31 
*Main> :break bla 
Breakpoint 2 activated at bla1.hs:5:1-19 
*Main> blabla [1,2,3] 
Stopped at bla1.hs:7:1-36 
_result :: Int = _ 
[bla1.hs:7:1-36] *Main> :step 
Stopped at bla1.hs:7:17-36 
_result :: Int = _ 
xs :: [Int] = [1,2,3] 
[bla1.hs:7:17-36] *Main> :step 
Stopped at bla1.hs:6:1-31 
_result :: Int = _ 
[bla1.hs:6:1-31] *Main> :step 
Stopped at bla1.hs:6:17-31 
_result :: Int = _ 
x :: Int = 3 
y :: Int = _ 
[bla1.hs:6:17-31] *Main> :step 
Stopped at bla1.hs:6:1-31 
_result :: Int = _ 
[bla1.hs:6:1-31] *Main> :step 
Stopped at bla1.hs:6:17-31 
_result :: Int = _ 
x :: Int = 2 
y :: Int = _ 
[bla1.hs:6:17-31] *Main> :step 
Stopped at bla1.hs:6:1-31 
_result :: Int = _ 
[bla1.hs:6:1-31] *Main> :step 
Stopped at bla1.hs:6:17-31 
_result :: Int = _ 
x :: Int = 1 
y :: Int = 0 
[bla1.hs:6:17-31] *Main> :step 
Stopped at bla1.hs:5:1-19 
_result :: Int = _ 
[bla1.hs:5:1-19] *Main> :step 
Stopped at bla1.hs:5:17-19 
_result :: Int = _ 
x :: Int = 1 
[bla1.hs:5:17-19] *Main> :step 
Stopped at bla1.hs:5:1-19 
_result :: Int = _ 
[bla1.hs:5:1-19] *Main> :step 
Stopped at bla1.hs:5:17-19 
_result :: Int = _ 
x :: Int = 2 
[bla1.hs:5:17-19] *Main> :step 
Stopped at bla1.hs:5:1-19 
_result :: Int = _ 
[bla1.hs:5:1-19] *Main> :step 
Stopped at bla1.hs:5:17-19 
_result :: Int = _ 
x :: Int = 3 
[bla1.hs:5:17-19] *Main> :step 
0 
*Main> 

उत्तर

0

हास्केल आप के लिए शाब्दिक अभिव्यक्ति के माध्यम से कदम नहीं करता है।

e = 2*(2+2) 

की तरह कुछ तुरंत, 8 के रूप में मूल्यांकित क्योंकि संकलक शाब्दिक यह सिर्फ संकलन समय पर 'के आसपास बिछाने' पा सकते हैं से बना किसी भी भाव को अनुकूलित करेंगे होगा (अभिव्यक्ति के इस प्रकार एक निरंतर अनुप्रयोगी रूप कहा जाता है)।

अब आपको यह समझना होगा कि foldl आलसी है। यदि आप किसी सूची में foldl f पर कॉल करते हैं, तो यह f का एकल मूल्यांकन तब तक नहीं करेगा जब तक कि इसे ऐसा करने के लिए बिल्कुल मजबूर नहीं किया जाता है।

>foldl (+) 0 [1,2,3] 
>foldl (+) a1 [2,3] 
    where a1 = 0+1 
>foldl (+) a2 [3] 
    where a2 = a1+2 
      where a1 = 0+1 

अंततः हम ((0+1)+2)+3) है और संकलक कहते हैं, "ठीक है, हम हर सूची समाप्त हो और सबसे आदिम रूप में हम कर सकते करने के लिए हर मूल्यांकन का विस्तार किया है। देता है का मूल्यांकन"। और हम पहले से ही जानते हैं कि एक सीएएफ के मूल्यांकन के माध्यम से Haskell चरणबद्ध नहीं होगा।

यदि आप मूल्यांकन के मध्यवर्ती मूल्य देखना चाहते हैं तो आपको वास्तव में उन्हें पहले स्थान पर बनाना होगा। जिस तरह से आप यह कर foldl के निम्नलिखित सख्त संस्करण है:

foldl' f z []  = z 
foldl' f z (x:xs) = let z' = z `f` x 
        in seq z' $ foldl' f z' xs 

मैं यह पता लगाने की यह कैसे काम करता आप छोड़ देंगे, लेकिन seq a b पूरी तरह से evalutate a lazily b मूल्यांकन करने के लिए जारी रखने से पहले होगा।

foldl से foldl' को बदलने के अलावा, सबकुछ पहले जैसा करें। जब आप मूल्यांकन के माध्यम से कदम उठाते हैं, तो आप foldl' फ़ंक्शन के अंदर रोके जाने पर इंटरमीडिएट देखेंगे।

+0

आपके उत्तर के लिए धन्यवाद। हालांकि, सख्त मूल्यांकन पर स्विच करना मेरी इच्छा नहीं है, उस स्थिति में मैं 'बल' का भी उपयोग कर सकता हूं। मेरा इरादा 'ब्लै' और 'पेपरपरैप' के परिणाम का निरीक्षण करने में सक्षम होना है जब उनके परिणाम मूल्यों का मूल्यांकन किया गया है। और परिणाम प्राप्त करने के लिए: 'bla 1 = 2; papperlap 0 1 = 0; ब्लै 2 = 4; papperlap 0 2 = 0; ब्लै 3 = 6; papperlap 0 3 = 0; ब्लब्ला [1,2,3] = 0' –

3

अपने तत्काल डिबगिंग चिंताओं के लिए थोड़ी देर हो चुकी है, लेकिन यहाँ मैं क्या कर सकता है:

blabla :: [Int] -> Int 
bla  :: Int -> Int 
papperlap :: Int -> Int -> Int 

bla x   = (undefined :: Int) 
papperlap y x = ((y *) . bla) x 
blabla xs = foldl papperlap 0 xs 

अब हम जानते हैं कि हम bla के मूल्यांकन में एक अपवाद मिल जाएगा। तो चलो GHCi में छोड़ दें:

[1 of 1] Compiling Main    (temp.hs, interpreted) 
Ok, modules loaded: Main. 
λ: :set -fbreak-on-exception 
λ: :trace blabla [1,5,17] 
Stopped at <exception thrown> 
_exception :: e = _ 
λ: :hist 
-1 : bla (temp.hs:6:17-35) 
-2 : bla (temp.hs:6:1-35) 
-3 : papperlap (temp.hs:7:17-31) 
-4 : papperlap (temp.hs:7:1-31) 
-5 : papperlap (temp.hs:7:17-31) 
-6 : papperlap (temp.hs:7:1-31) 
-7 : papperlap (temp.hs:7:17-31) 
-8 : papperlap (temp.hs:7:1-31) 
-9 : blabla (temp.hs:8:13-32) 
-10 : blabla (temp.hs:8:1-32) 
<end of history> 
λ: :back 
Logged breakpoint at temp.hs:6:17-35 
_result :: a 
λ: :list 
5 
6 bla x   = (undefined :: Int) 
        ^^^^^^^^^^^^^^^^^^^ 
7 papperlap y x = ((y *) . bla) x 
λ: :back 
Logged breakpoint at temp.hs:6:1-35 
_result :: a 
λ: :list 
5 
6 bla x   = (undefined :: Int) 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
7 papperlap y x = ((y *) . bla) x 
λ: :back 
Logged breakpoint at temp.hs:7:17-31 
_result :: Int 
x :: Int 
y :: Int 
λ: :list 
6 bla x   = (undefined :: Int) 
7 papperlap y x = ((y *) . bla) x 
        ^^^^^^^^^^^^^^^ 
8 blabla xs = foldl papperlap 0 xs 

और इसलिए हम ढेर bla के दाएँ हाथ की ओर के मूल्यांकन करने के लिए अग्रणी देख सकते हैं।

यह undefined रों में डालने के बाद से हर जगह चिपचिपा और hacky लगता है, सही नहीं है, लेकिन :hist आप काफ़ी पहले से ही पर काम करने के :list का उपयोग कर के रूप में आप पीछे हटना बातें भी स्पष्ट करता है देता है, और।

संबंधित मुद्दे