2016-02-10 5 views
7

LYAH पढ़ना, मैं कोड के इस टुकड़े पर ठोकर खाई:क्या उच्च आदेश polymorphism तर्क के सख्त आदेश की आवश्यकता है?

newtype Writer w a = Writer { runWriter :: (a, w) } 

instance (Monoid w) => Monad (Writer w) where 
    return x = Writer (x, mempty) 
    (Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v') 

को समझने के लिए क्या बिल्ली पहली पंक्ति में Writer w है प्रयास करते समय, मुझे पता चला यह एक पूर्ण प्रकार नहीं किया जा रहा है, लेकिन साथ प्रकार निर्माता का एक प्रकार 1 तर्क, के लिए Maybe String

Maybe जैसे महान लग रहा है, लेकिन क्या हुआ अगर प्रारंभिक प्रकार यदि Writer' इस तरह, बदली प्रकार तर्क के साथ परिभाषित किया गया है:

newtype Writer' a w = Writer' { runWriter :: (a, w) } 

क्या अब मोनाड इंस्टेंस को कार्यान्वित करना संभव है? कुछ इस तरह है, लेकिन क्या वास्तव में संकलित किया जा सकता है: एक प्रकार तर्क गुम साथ एक प्रकार निर्माता - इस समय पहले एक:

instance (Monoid w) => Monad (\* -> Writer' * monoid) where 

\* -> Writer' * monoid के विचार एक ही रूप में Writer w है।

+2

आप 'मोनाड' उदाहरण रखने के स्पष्ट उद्देश्य के लिए 'राइटर' को परिभाषित करते हैं। स्वैच्छिक तर्कों के साथ इसे परिभाषित करने का कोई मतलब नहीं है। और यदि आप निर्णायक प्रकार की जांच करना चाहते हैं तो आप इस प्रकार के स्तर के कार्यों को नहीं लिख सकते हैं। –

उत्तर

9

हास्केल में यह संभव नहीं है, आपको एक प्रकार का स्तर लैम्ब्डा फ़ंक्शन है, जो अस्तित्व में नहीं है।

प्रकार समानार्थी शब्द है जो आप प्रकार चर के reorderings परिभाषित करने के लिए उपयोग कर सकते हैं कर रहे हैं:

type Writer'' a w = Writer' a w 

लेकिन आप आंशिक रूप से लागू किया प्रकार समानार्थी शब्दों के लिए वर्ग उदाहरणों (यहां तक ​​कि TypeSynonymInstances विस्तार के साथ) नहीं दे सकता।

मैंने अपने एमएससी थीसिस को इस प्रकार के विषय के बारे में लिखा कि कैसे टाइप-लेवल लैम्बडास को जीएचसी में जोड़ा जा सकता है: https://xnyhps.nl/~thijs/share/paper.pdf टाइप-क्लास इंस्टेंस में टाइप अनुमान के बलिदान के बिना इस्तेमाल किया जा सकता है।

+0

तो, स्कैला में लैम्ब्डा प्रकार क्या है! .. ठीक है? –

+0

वास्तव में, संबंधित कार्य में एक उदाहरण है कि यह स्कैला में कैसे काम करता है। स्कैला के लिए व्यापार-बंद यह है कि टाइप क्लास का उपयोग करते समय आपको लगभग हमेशा एनोटेशन देने की आवश्यकता होती है। – xnyhps

5

जो आप यहां देख रहे हैं वह हैस्केल का एक पैराचियल डिज़ाइन विकल्प है। यह सही अर्थ, अवधारणात्मक रूप से बोलने के लिए कहता है कि आपका Writer' प्रकार एक मज़ेदार है यदि आप अपना पहला पैरामीटर "छोड़ दें"। और ऐसी घोषणाओं की अनुमति देने के लिए एक प्रोग्रामिंग भाषा वाक्यविन्यास का आविष्कार किया जा सकता है।

हास्केल समुदाय ने ऐसा नहीं किया है, क्योंकि उनके पास अपेक्षाकृत सरल है और यह काफी अच्छी तरह से काम करता है। यह कहना नहीं है कि वैकल्पिक डिज़ाइन संभव नहीं हैं, लेकिन इस तरह के डिज़ाइन को अपनाया जाना होगा:

  1. हमारे पास पहले से मौजूद अभ्यास से अधिक जटिल नहीं होना चाहिए;
  2. स्विच कार्यक्षमता या लाभ जो स्विच के लायक होगा।

यह हास्केल समुदाय प्रकारों का उपयोग करने के कई अन्य तरीकों से सामान्यीकृत करता है; अक्सर एक प्रकार के भेद के रूप में कुछ का प्रतिनिधित्व करने का विकल्प भाषा के डिजाइन के कुछ आर्टिफैक्ट से जुड़ा हुआ है।कई इकाई ट्रांसफार्मर अच्छे उदाहरण, MaybeT की तरह हैं:

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } 

instance Functor m => Functor (MaybeT m) where ... 
instance Applicative m => Applicative (MaybeT m) where ... 
instance Monad m => Monad (MaybeT m) where ... 
instance MonadTrans MaybeT where ... 

चूंकि यह एक newtype है, इसका मतलब है कि MaybeT IO StringisomorphicIO (Maybe String) है, आप मूल्यों के एक ही सेट पर दो "दृष्टिकोण" होने के रूप में दो प्रकार के बारे में सोच सकते हैं:

  1. IO (Maybe String) एक IO कार्रवाई उस प्रकार Maybe String के मूल्यों का उत्पादन होता है;
  2. MaybeT IO StringMaybeT IO क्रिया है जो String प्रकार के मान उत्पन्न करती है।

दृष्टिकोण के बीच अंतर यह है कि वे Monad संचालन के विभिन्न कार्यान्वयन को इंगित करते हैं। हास्केल में तो यह भी निम्न संकीर्ण तकनीकी तथ्यों से जुड़ा हुआ है:

  • एक String पिछले प्रकार पैरामीटर है ("मूल्यों") और अन्य Maybe String है;
  • IO और MaybeT IOMonad कक्षा के लिए अलग-अलग उदाहरण हैं।

लेकिन शायद वहाँ एक भाषा डिजाइन तुम कहाँ कह सकते हैं प्रकार IO (Maybe a) एक इकाई अधिक सामान्य IO a प्रकार के लिए इकाई से यह करने के लिए विशिष्ट है, और अलग हो सकता है है। उस भाषा को कुछ जटिलता को उस भेद को लगातार बनाने के लिए जटिलता होगी (उदाहरण के लिए, Monad उदाहरण IO (Maybe String) के लिए डिफ़ॉल्ट रूप से निर्धारित करने के लिए नियम और प्रोग्रामर को डिफ़ॉल्ट पसंद को ओवरराइड करने की अनुमति देने के नियम)। और मैं विनम्रतापूर्वक दांव दूंगा कि अंतिम परिणाम हमारे पास जो कुछ भी है उससे कम जटिल नहीं होगा। टीएल; डीआर: मेह।

+0

यहां "पैरोकियल" का क्या मतलब है? – dfeuer

+2

हास्केल और उसके समुदाय के लिए विशिष्ट। कुछ श्रेणी सिद्धांत नोटेशन एक अलग सम्मेलन दिखाता है-लोग "* * × बी * मज़ेदार" जैसी चीजों के बारे में बात करते हैं जहां डैश * ए × बी * जैसी अभिव्यक्ति में "छेद" को संदर्भित करता है। हो सकता है कि कोई व्यक्ति एक भाषा डिज़ाइन के साथ आ सकता है जहां आप 'इंस्टेंस मोनॉयड एम => मोनाड (राइटर' _ मीटर) 'या 'इंस्टोन मोनॉयड एम => मोनाड (\ a -> राइटर' एम) या कुछ कह सकते हैं। हास्केल में हमारे पास यह मुख्य कारण नहीं है, मैं दलील दूंगा, क्योंकि हम जो करते हैं वह ठीक काम करता है! –

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