2017-12-09 87 views
6

मैं Cloud Haskell के साथ खेल रहा हूं। मैंने देखा है in the hackage documentation एक प्रकार का आवेदक इंटरफ़ेस है। लेकिन विशेष रूप से मुझे लगता है या निम्न हस्ताक्षर के साथ एक समारोह closurePure लिखने के लिए कोशिश कर रहा हूँ:क्लाउड हास्केल - क्लोजर के लिए "शुद्ध" कैसे लिखें?

closurePure :: (Typeable a, Binary a) => a -> Closure a 

यह मूलतः शुद्ध की एक सीमित संस्करण है।

जबकि Closure डेटाप्रकार ही सार है, निम्नलिखित closure प्रदान की:

closure :: Static (ByteString -> a) -> ByteString -> Closure a 

तो मैं इस अब तक प्राप्त कर सकते हैं:

closurePure :: (Typeable a, Binary a) => a -> Closure a 
closurePure x = closure ??? (encode x) 

समस्या क्या डाल करने के लिए जहां ??? रों हो रहा है।

myDecode :: (Typeable a, Binary a) => Static (ByteString -> a) 
myDecode = staticPtr (static decode) 

लेकिन GHC docs on static pointers पढ़ने के बाद show उदाहरण मेरे लिए सुझाव दिया है कि आप एक बाधा नहीं हो सकता है क्योंकि एक विवश समारोह एक Typeable उदाहरण नहीं है:

मेरा पहला प्रयास के बाद किया गया था। इसलिए मैं काम करने की कोशिश की चारों ओर Dict का उपयोग कर सुझाव:

myDecode :: Typeable a => Static (Dict (Binary a) -> ByteString -> a) 
myDecode = staticPtr (static (\Dict -> decode)) 

लेकिन अब मैं गलत प्रकार है कि ऊपर closure समारोह में फिट नहीं बैठता मिल गया है।

क्या closurePure लिखने के लिए वैसे भी कुछ है (या क्या मैंने क्लाउड हास्केल डॉक्स में इसे याद किया है)? binary सादा प्रकार Closure एस को आवेदक इंटरफ़ेस का उपयोग करने के लिए आवश्यक लगता है, लेकिन मैं यह नहीं कर सकता कि इसे कैसे किया जाए।

ध्यान दें कि मैं यह कर सकता:

class StaticDecode a where 
    staticPtrDecode :: StaticPtr (ByteString -> a) 

instance StaticDecode Int where 
    staticPtrDecode = static Data.Binary.decode 

instance StaticDecode Float where 
    staticPtrDecode = static Data.Binary.decode 

instance StaticDecode Integer where 
    staticPtrDecode = static Data.Binary.decode 

-- More instances etc... 

myPure :: forall a. (Typeable a, StaticDecode a, Binary a) => a -> Closure a 
myPure x = closure (staticPtr staticPtrDecode) (encode x) 

कौन सा अच्छा काम करता है लेकिन मूल रूप से मुझे हर Binary उदाहरण के लिए एक उदाहरण दोहराने की आवश्यकता है। यह गन्दा लगता है और मैं एक और तरीका पसंद करेंगे।

+0

क्या आप सुनिश्चित हैं कि 'myDecode = staticPtr (static decode) 'काम नहीं करता है? ऐसा लगता है कि आपने 'स्टेटिक डिकोड' बाधा के लिए 'बाइनरी' बाधा का व्यापार किया है, लेकिन आप कहते हैं कि यह काम कर रहा है। – 4castle

+0

क्षमा करें, अंतिम कार्य को 'myPure'' कहा जाना चाहिए, न कि 'myDecode'। उम्मीद है कि अधिक समझ में आता है। लेकिन एक मायने में आप सही हैं, लेकिन 'स्टेटिकडेकोड' उदाहरण के अंदर मैं स्थिर (जो काम करता है) को कॉल कर रहा हूं लेकिन जब मैं बाइनरी इंस्टेंस से पहले 'डीकोड' लेता हूं तो स्थिर लागू होता है। मुझे अनुमान है (यह पूरी तरह से अनुमान है) कि 'स्टेटिकडेकोड' का प्रत्येक उदाहरण एक अद्वितीय स्थैतिक सूचक उत्पन्न करता है, इसलिए यह ठीक काम करता है। – Clinton

उत्तर

4

आप सही हैं, Closure एक applicative-जैसी संरचना, एक तथ्य यह दोनों इंटरफेस और distributed-closure के कार्यान्वयन में और भी अधिक स्पष्ट किया है। यह काफी आवेदक नहीं है, क्योंकि pure मामले में हमारे पास अतिरिक्त बाधा है कि तर्क किसी भी तरह से क्रमिक होना चाहिए।

वास्तव में, हमारे पास एक मजबूत बाधा है। न केवल तर्क को क्रमिक होना चाहिए, लेकिन बाधा स्वयं ही धारावाहिक होना चाहिए। जैसे ही सीधे कार्यों को क्रमबद्ध करना मुश्किल है, आप कल्पना कर सकते हैं कि बाधाओं को क्रमबद्ध करना मुश्किल है। लेकिन फ़ंक्शंस की तरह ही, चाल एक स्थैतिक सूचक को बाधा के लिए क्रमबद्ध करने के लिए है, यदि ऐसा स्थिर सूचक मौजूद है। हम कैसे जानते हैं कि ऐसा सूचक मौजूद है? हम एक भी विधि हमें सूचक का नाम देता है कि के साथ एक प्रकार वर्ग को पेश कर सकता है, की कोई समस्या नहीं दिया गया:

class GimmeStaticPtr c where 
    gimmeStaticPtr :: StaticPtr (Dict c) 

एक मामूली तकनीकी चाल यहाँ पर जा रहा है। StaticPtr के लिए प्रकार इंडेक्स की तरह * है, जबकि एक बाधा दयालु Constraint है। इसलिए हम constraints लाइब्रेरी से एक चाल का पुन: उपयोग करते हैं जिसमें डेटा प्रकार (Dict ऊपर) में बाधा डालने में शामिल होता है, जो सभी डेटा प्रकारों की तरह * है। GimmeStaticPtr उदाहरण से जुड़ी बाधाओं को स्थैतिक बाधाओं कहा जाता है।

सामान्यतः, कभी-कभी स्थिर स्थिर बाधाओं को प्राप्त करने के लिए स्थिर बाधाओं को लिखना उपयोगी होता है। StaticPtr संगत नहीं है, लेकिन Closure है।तो क्या वास्तव में distributed-closure करता है, इसी तरह की एक वर्ग को परिभाषित है कि हम फोन करता हूँ,

class GimmeClosure c where 
    gimmeClosure :: Closure (Dict c) 

अब हम एक ऐसी ही रास्ता है कि तुमने किया था में closurePure परिभाषित कर सकते हैं:

closurePure :: (Typeable a, GimmeClosure (Binary a)) => a -> Closure a 

यह बहुत अच्छा होगा अगर में भविष्य में, संकलक आवश्यकतानुसार स्थिर पॉइंटर्स उत्पन्न करके GimmeClosure बाधाओं को ऑन-द-फ्लाई को हल कर सकता है। लेकिन अभी के लिए, निकटतम चीज टेम्पलेट हास्केल है। वितरित-बंद कक्षा Cls के लिए परिभाषा साइट पर GimmeClosure (Cls a) बाधाओं को स्वत: उत्पन्न करने के लिए एक मॉड्यूल प्रदान करता है। withStatichere देखें।

संयोग से, एडस्को डी वेरी ने वितरित बंद होने और इसमें शामिल विचारों के बारे में great talk दिया।

2

चलो इस बात पर विचार करने के लिए एक पल लें कि आप क्या पूछ रहे हैं। याद रखें कि टाइपक्लास मूल रूप से गुजरने के लिए शॉर्टेंड हैं। तो चलो फिर से लिखने करते हैं: हम देख सकते हैं कि क्या स्पष्ट रूप से चल रहा है, हम देख सकते हैं

closurePure bdict = closure (staticPtr (static (bdDecode bdict))) . bdEncode bdict 

अब:

closurePure :: (Typeable a) => BinaryDict a -> a -> Closure a 

आपका प्रयास है:

data BinaryDict a = BinaryDict 
    { bdEncode :: a -> ByteString 
    , bdDecode :: ByteString -> a 
    } 

अब आप एक समारोह लिखना चाहते हैं कि static का तर्क बंद नहीं किया जा सकता है। यदि BinaryDict एस को उपयोगकर्ता डेटा से कहने के लिए अनुमति दी गई थी, तो यह कार्य असंभव होगा। हम बजाय आवश्यकता होगी:

closurePure :: (Typeable a) => Static (BinaryDict a) -> a -> Closure a 

है यही कारण है कि, हम स्थिर सूचक तालिका में जरूरत Binary उदाहरण के लिए प्रविष्टियों की जरूरत है। इसलिए आपका गणित समाधान, और मुझे संदेह है कि ऐसा समाधान आवश्यक है।हम भी स्वचालित रूप से गणना करने की उम्मीद नहीं कर सकते हैं, क्योंकि असीमित कई उदाहरण हैं।

यह मेरे लिए मूर्खतापूर्ण प्रतीत होता है, हालांकि, उदाहरण केवल उन चीजों की तरह लगते हैं जिन्हें आप स्थिर होना चाहते हैं। वे प्रकृति से स्थैतिक हैं (वह क्या है, reflection? मैं आपको नहीं सुन सकता)। यह शायद वितरित हास्केल पत्रों में कम से कम ruminated था (मैंने उन्हें पढ़ा नहीं है)।

हम इस वर्ग को सामान्य रूप से एक वर्ग बनाकर हल कर सकते हैं जो प्रत्येक वर्ग (déjà vu?) के प्रत्येक उदाहरण को ठोस रूप से समझाता है।

class c => StaticConstraint c where 
    staticConstraint :: StaticPtr (Dict c) 
instance StaticConstraint (Show Int) where 
    staticConstraint = static Dict 
-- a handful more lines... 

कुछ हद तक और अधिक गंभीरता से, यदि आप वास्तव में नहीं है की गणना करने में (मैं तुम्हें दोष नहीं है), आप कम से कम एक कॉलिंग सम्मेलन के दर्द को कम कर सकते हैं:

closurePure :: (Typeable a, Binary a) => StaticPtr (ByteString -> a) -> a -> Closure a 
closurePure decodePtr = closure (staticPtr decodePtr) . encode 

someClosure :: Closure Int 
someClosure = closurePure (static decode) 42 

यह बकवास आवश्यक है क्योंकि static फ़ंक्शन के बजाए एक "वाक्य रचनात्मक रूप" है - इसका उल्लेख करके, हम इंगित करते हैं कि BinaryInt के लिए उदाहरण वास्तव में स्थिर सूचक तालिका में उत्पन्न और दर्ज किया जाना चाहिए।

आप मुखर महसूस कर रहे हैं के लिए सक्षम हो सकता है {-# LANGUAGE CPP #-} और

-- PURE :: (Binary a, Typeable a) => a -> Closure a, I promise 
#define PURE (closurePure (static decode)) 

someClosure :: Closure Int 
someClosure = PURE 42 

हो सकता है कि किसी दिन हास्केल के लिए अगले कदम और स्नातक लगेगा समय परीक्षण अपने पूर्ववर्तियों की Segmentation fault (core dumped) उन अभिमानी प्रकार त्रुटियों बंद फुहार छोड़ती के बजाय।

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