2011-09-13 17 views
10

हो रहा है मैं बादल हास्केल पैकेज के Encoding.hs से अधिक देख रहा हूँ, और कुछ अजीब कोड है कि मुझे उम्मीद थी किसी की मदद कर सकता है मुझे बेहतर ढंग से समझने का सामना करना पड़ा।Haskell जादुई कोड, यहाँ क्या

class (Binary a,Typeable a) => Serializable a 
instance (Binary a,Typeable a) => Serializable a 

data Payload = Payload 
    { 
     payloadType :: !ByteString, 
     payloadContent :: !ByteString 
    } deriving (Typeable) 

serialDecodePure :: (Serializable a) => Payload -> Maybe a 
serialDecodePure a = (\id -> 
    let pc = payloadContent a 
    in pc `seq` 
     if (decode $! payloadType a) == show (typeOf $ id undefined) 
     then Just (id $! decode pc) 
     else Nothing) id 

मैं के बारे में क्या $ बस उत्सुक हूँ: शामिल आवश्यक कोड है! करता है (मैं अनुमान लगा रहा हूं कि सख्ती से मूल्यांकन किया जाता है), और हमें आईडी चाल की आवश्यकता क्यों है (आलसी मूल्यांकन के साथ कुछ?)। इसके अलावा, मैं विशेष रूप से इस लाइन के साथ समस्या हो रही हूँ:

if (decode $! payloadType a) == show (typeOf $ id undefined) 

मैं अगर PayloadType जो भी कारण के लिए अमान्य है यह देख रहा है अनुमान लगा रहा हूँ, लेकिन अगर वह यह है कि मामला नहीं तो और बाकी खंड बंद किया जाना चाहिए, यानी परिवर्तन:

if (decode $! payloadType a) == show (typeOf $ id undefined) 
    then Just (id $! decode pc) 
    else Nothing 

को
if (decode $! payloadType a) == show (typeOf $ id undefined) 
    then Nothing 
    else Just (id $! decode pc) 

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

+0

हां, 'एफ $! एक्स' सख्त आवेदन है। आपको [इस आलेख] (http://neilmitchell.blogspot.com/2008/05/bad-strictness.html) सख्तता जोड़ने के तरीके के बारे में प्रबुद्ध हो सकता है। –

+0

यह भी देखें http://stackoverflow.com/q/2787543/246886 –

उत्तर

12

आप सही है कि $! एक सख्त मूल्यांकनकर्ता है कर रहे हैं। यह प्रकार $ के समान है, और एकमात्र अर्थपूर्ण अंतर यह है कि समारोह में पारित होने से पहले दूसरा तर्क seq 'डी है।

मुझे लगता है कि वास्तव में id है प्रकार निष्कर्ष में मदद करेगा। समारोह ब्लॉक (\id -> ...) के भीतर, समारोह id प्रकार a -> a, जहां a बस किसी भी प्रकार चर नहीं है के लिए मजबूर किया जाता है, लेकिन एक ही a

serialDecodePure :: (Serializable a) => Payload -> Maybe a 

में के रूप में यह इस लाइन की वजह से है:

Just (id $! decode pc) 

क्योंकि इस प्रकार Maybe a, id का अनुमानित प्रकार a -> a है।परिणामस्वरूप, लाइन पर आप

if (decode $! payloadType a) == show (typeOf $ id undefined) 

id undefined :: a, जहां a फिर से आउटपुट के रूप में एक ही है, पर देख रहे हैं।

अब हम प्रकार की जांच कर सकते हैं। चूंकि यह फ़ंक्शन polymorphic है और किसी भी प्रकार को डीकोड करेगा, इसलिए यह जांचने की आवश्यकता है कि एन्कोडेड डेटा उस प्रकार के साथ संगत है जिस प्रकार यह डीकोडिंग है। क्या होगा यदि आपने String एन्कोड किया है और Int पर डीकोड करने का प्रयास कर रहे हैं? एलएचएस "[चार]" को डीकोड करेगा, जो एक स्ट्रिंग का टाइपरप प्रतिनिधित्व है। आरएचएस इसके बजाय "इंट" होगा, जिस प्रकार से यह डीकोड करने का प्रयास कर रहा है। चूंकि वे बराबर नहीं हैं, इसलिए "अन्य" पथ वह है जो None देता है।

इस आईडी फ़ंक्शन प्रकार प्रतिबंध के बजाय, आप ScopedTypeVariables एक्सटेंशन के साथ एक ही चीज़ को पूरा कर सकते हैं।

+1

ओह आदमी कि आईडी चीज रास्ता चालाक है –

4

वाह, यह कुछ अजीब दिखने कोड है! आप अनुमान लगा लिया होगा, ($!) कठोरता के बारे में है:

f $! x = x `seq` f x 

id चाल sneakier है, और सभी के बारे में लेखन प्रतिबंध है। आप देखेंगे कि id फ़ंक्शन बॉडी में दो बार उपयोग किया जाता है। दूसरी बार इसे id $! decode pc के रूप में उपयोग किया जाता है; decode आउटपुट पर किसी भी प्रकार की चीज़ों को संचालित करने के लिए यह id के प्रकार को हल करता है। पहला उपयोग typeOf $! id undefined के रूप में है; के बाद से id के प्रकार पहले से ही तय किया गया है, इस undefined के प्रकार ताकि typeOf एक monomorphic तर्क को लागू किया जाता है (और आप "अस्पष्ट प्रकार" त्रुटियों नहीं मिलता है) ठीक करता है,। इस तरह की चीज अक्सर इस चालबाजी के बजाय ScopedTypeVariables एक्सटेंशन के साथ की जाती है, लेकिन शायद वे जहां भी संभव हो एक्सटेंशन से बचना चाहते थे। इस का अर्थ के लिए के रूप में:

(decode $! payloadType a) == show (typeOf $ id undefined) 

... ऐसा जाँच कर रहा है कि पेलोड बात then शाखा में decode करने के लिए कॉल द्वारा लौटाए के प्रकार से मेल खाता है मेरे लिए लग रहा है। ऐसा लगता है कि जब वे मेल खाते हैं, तो Just मान (यानी सफलता) होने का अर्थ होता है, और Nothing मान (यानी विफलता) जब वे नहीं करते हैं।