के लिए दोहराव नोटेशन मैं कॉनोर मैकब्राइड के "क्रूरिसली तीर का अपमानजनक भाग्य" पेपर का पालन कर रहा था और मैंने अपने कोड 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
सिंटैक्स का उपयोग करें।
अब, मुझे पता है कि "राक्षसी बांध" का उपयोग करने में एक और समस्या है, जिसे आप (>>)
परिभाषित नहीं कर सकते हैं, लेकिन मैं अभी भी देखना चाहता हूं कि मैं इसके साथ कितना दूर जा सकता हूं। क्या कोई यह समझा सकता है कि मैं "राक्षसी बांध" को बेकार करने के लिए जीएचसी क्यों नहीं प्राप्त कर सकता, भले ही यह आमतौर पर टाइप-चेक करे?
चूंकि यह एक [नए डुप्लिकेट प्रश्न] में आया था (http://stackoverflow.com/questions/33488322/ranknpolymorphism-and-kleisli-arrows-of-outrageous-fortune), मैं बताता हूं कि आजकल जीएचसी (वर्तमान में 7.10.2) शायद ही कभी 'ImpredicativeTypes' का समर्थन करता है, इसलिए अब इस कोड के लिए 'do' नोटेशन ब्रेक से बहुत अधिक है। –