2012-06-14 10 views
21

के लिए दोहराव नोटेशन मैं कॉनोर मैकब्राइड के "क्रूरिसली तीर का अपमानजनक भाग्य" पेपर का पालन कर रहा था और मैंने अपने कोड here के कार्यान्वयन को पोस्ट किया है।अनुक्रमित मोनैड

type a :-> b = forall i . a i -> b i 

class IFunctor f where imap :: (a :-> b) -> (f a :-> f b) 

class (IFunctor m) => IMonad m where 
    skip :: a :-> m a 
    bind :: (a :-> m b) -> (m a :-> m b) 

data (a := i) j where 
    V :: a -> (a := i) i 

फिर वह जिनमें से बाद (:=) का उपयोग करता प्रारंभिक अनुक्रमणिका को प्रतिबंधित करने के लिए बांधता के दो प्रकार, परिभाषित करता है::

-- Conor McBride's "demonic bind" 
(?>=) :: (IMonad m) => m a i -> (a :-> m b) -> m b i 
(?>=) = flip bind 

-- Conor McBride's "angelic bind" 
(>>=) :: (IMonad m) => m (a := j) i -> (a -> m b j) -> m b i 
m >>= f = bind (\(V a) -> f a) m 

बाद बाँध पूरी तरह से ठीक काम करता है संक्षेप में, वह निम्न प्रकार के और वर्गों को परिभाषित करता है

: return और fail के लिए do अंकन rebinding RebindableSyntax विस्तार के साथ अनुक्रमित monads उपयोग करने के लिए, निम्न इसी परिभाषाओं का उपयोग के लिए

... लेकिन समस्या यह है कि मुझे पूर्व बांध नहीं मिल सकता है (यानी। काम करने के लिए (?>=))। मैं बजाय (>>=) और return को परिभाषित करने की कोशिश की जा करने के लिए:

(>>=) :: (IMonad m) => m a i -> (a :-> m b) -> m b i 
(>>=) = (?>=) 

return :: (IMonad m) => a :-> m a 
return = skip 

तो मैं एक विशिष्ट सूचकांक में निवास करने की गारंटी एक डेटा प्रकार बनाया:

data Unit a where 
    Unit :: Unit() 

लेकिन जब मैं के लिए नए परिभाषाओं का उपयोग do अंकन rebind करने की कोशिश (>>=) और return, यह काम नहीं करता, जैसा कि निम्न उदाहरण में बताया:

-- Without do notation 
test1 = skip Unit >>= \Unit -> skip Unit 

-- With do notation 
test2 = do 
    Unit <- skip Unit 
    skip Unit 

test1 प्रकार-जांच करता है, लेकिन test2 क्यों test2 नहीं है जो अजीब है, के बाद से मैं test1 करने के लिए सभी कि RebindableSyntax किया जाने दिया गया do अंकन desugar test2 सोचा है, इसलिए यदि test1 प्रकार-जांच नहीं करता है,, तो? त्रुटि मैं मिलता है:

Couldn't match expected type `t0 -> t1' 
      with actual type `a0 :-> m0 b0' 
Expected type: m0 a0 i0 -> (t0 -> t1) -> m Unit() 
    Actual type: m0 a0 i0 -> (a0 :-> m0 b0) -> m0 b0 i0 
In a stmt of a 'do' block: Unit <- skip Unit 
In the expression: 
    do { Unit <- skip Unit; 
     skip Unit } 

त्रुटि भी बनी हुई है जब मैं :-> प्रकार ऑपरेटर के बजाय स्पष्ट forall सिंटैक्स का उपयोग करें।

अब, मुझे पता है कि "राक्षसी बांध" का उपयोग करने में एक और समस्या है, जिसे आप (>>) परिभाषित नहीं कर सकते हैं, लेकिन मैं अभी भी देखना चाहता हूं कि मैं इसके साथ कितना दूर जा सकता हूं। क्या कोई यह समझा सकता है कि मैं "राक्षसी बांध" को बेकार करने के लिए जीएचसी क्यों नहीं प्राप्त कर सकता, भले ही यह आमतौर पर टाइप-चेक करे?

+0

चूंकि यह एक [नए डुप्लिकेट प्रश्न] में आया था (http://stackoverflow.com/questions/33488322/ranknpolymorphism-and-kleisli-arrows-of-outrageous-fortune), मैं बताता हूं कि आजकल जीएचसी (वर्तमान में 7.10.2) शायद ही कभी 'ImpredicativeTypes' का समर्थन करता है, इसलिए अब इस कोड के लिए 'do' नोटेशन ब्रेक से बहुत अधिक है। –

उत्तर

9

आईआईयूसी, जीएचसी desugarer वास्तव में टाइपशेकर (source) के बाद चलाता है। यह बताता है कि आप जिस स्थिति का पालन करते हैं वह सैद्धांतिक रूप से संभव है। टाइपशेकर में संभवतया डू-नोटेशन के लिए कुछ विशेष टाइपिंग नियम हैं, और वे टाइपशेकर के साथ असंगत कोड के साथ क्या असंगत हो सकते हैं।

बेशक, यह सुनिश्चित करना उचित है कि वे लगातार बने रहें, इसलिए मैं एक जीएचसी बग दर्ज करने की सिफारिश करता हूं।

+2

लिंक के लिए धन्यवाद। मैं इसे देखूंगा। अगर वे सहमत हैं कि टाइप त्रुटि का कारण है तो मैं आपका जवाब स्वीकार करूंगा। –

+2

मैं यह जानना चाहता हूं कि क्या हो रहा है। मुझे एक ही समस्या का सामना करना पड़ा, लेकिन कम उत्तेजित था। मुझे उम्मीद है कि राक्षसी बहुरूपता अप्रत्याशित थी: यह बहुत से लोगों को हैरान कर रहा है। – pigworker

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