लैंबडा शब्दों के लिए इस प्रतिनिधित्व पर विचार करें जो उनके मुक्त चर द्वारा पैराट्राइक किया गया है। (बेलीगार्ड और हुक 1994, बर्ड एंड पैटरसन 1999, अल्टेंकिर्च और रीस 1999 द्वारा पत्र देखें।)
data Tm a = Var a
| Tm a :$ Tm a
| Lam (Tm (Maybe a))
आप निश्चित रूप से इसे बना सकते हैं Functor, नाम बदलने की धारणा को कैप्चर कर सकते हैं , और Monadप्रतिस्थापन की धारणा को कैप्चर कर सकते हैं।
instance Functor Tm where
fmap rho (Var a) = Var (rho a)
fmap rho (f :$ s) = fmap rho f :$ fmap rho s
fmap rho (Lam t) = Lam (fmap (fmap rho) t)
instance Monad Tm where
return = Var
Var a >>= sig = sig a
(f :$ s) >>= sig = (f >>= sig) :$ (s >>= sig)
Lam t >>= sig = Lam (t >>= maybe (Var Nothing) (fmap Just . sig))
अब बंद शब्दों पर विचार करें : ये वहां के निवासी हैं Tm Void। आपको मनमानी मुक्त चर के साथ बंद शर्तों को एम्बेड करने में सक्षम होना चाहिए। कैसे?
fmap absurd :: Tm Void -> Tm a
बेशक, यह है कि यह फ़ंक्शन शब्द को कुछ भी नहीं करने के लिए पीछे ले जाएगा। लेकिन यह एक स्पर्श से अधिक ईमानदार है unsafeCoerce। और इसीलिए vacuousइसे जोड़ा गया Data.Void...
या एक मूल्यांकनकर्ता लिखें। यहाँ मुफ्त चर के साथ मूल्य हैं b।
data Val b
= b :$$ [Val b] -- a stuck application
| forall a. LV (a -> Val b) (Tm (Maybe a)) -- we have an incomplete environment
मैंने अभी-अभी बंदियों के रूप में लैंबडास का प्रतिनिधित्व किया है। मूल्यांकनकर्ता एक पर्यावरण है जो aमूल्यों पर मुफ्त चर का मानचित्रण करता है b।
eval :: (a -> Val b) -> Tm a -> Val b
eval g (Var a) = g a
eval g (f :$ s) = eval g f $$ eval g s where
(b :$$ vs) $$ v = b :$$ (vs ++ [v]) -- stuck application gets longer
LV g t $$ v = eval (maybe v g) t -- an applied lambda gets unstuck
eval g (Lam t) = LV g t
आपने यह अनुमान लगाया। किसी भी लक्ष्य पर एक बंद शब्द का मूल्यांकन करने के लिए
eval absurd :: Tm Void -> Val b
अधिक आम तौर पर, Voidशायद ही कभी इसका उपयोग किया जाता है, लेकिन जब आप एक प्रकार के पैरामीटर को एक तरह से तुरंत रोकना चाहते हैं तो यह आसान होता है जो किसी प्रकार की असंभवता (जैसे, यहां, एक बंद अवधि में मुफ्त चर का उपयोग करके) को इंगित करता है। अक्सर इन parametrized प्रकार उच्च क्रम कार्यों के संचालन के लिए पूरे प्रकार पर मानकों के आधार पर संचालन उठाने के साथ आते हैं (जैसे, यहाँ, fmap, >>=, eval)। तो आप absurdसामान्य-उद्देश्य ऑपरेशन के रूप में पास करते हैं Void।
एक अन्य उदाहरण के लिए, Either e vकम्प्यूटेशन पर कब्जा करने के लिए उपयोग करने की कल्पना करें, जो आपको उम्मीद है कि आप एक vप्रकार का अपवाद उठा सकते हैं e। आप समान रूप से बुरे व्यवहार के जोखिम के दस्तावेज़ के लिए इस दृष्टिकोण का उपयोग कर सकते हैं। इस सेटिंग में पूरी तरह से अच्छी तरह से व्यवहार किए गए संगणना के eलिए Void, फिर से उपयोग करें
either absurd id :: Either Void v -> v
सुरक्षित रूप से चलाने के लिए या
either absurd Right :: Either Void v -> Either e v
एक असुरक्षित दुनिया में सुरक्षित घटकों को एम्बेड करने के लिए।
ओह, और एक आखिरी तूफान, "नहीं हो सकता" को संभालना। यह सामान्य जिपर निर्माण में दिखाता है, हर जगह कि कर्सर नहीं हो सकता है।
class Differentiable f where
type D f :: * -> * -- an f with a hole
plug :: (D f x, x) -> f x -- plugging a child in the hole
newtype K a x = K a -- no children, just a label
newtype I x = I x -- one child
data (f :+: g) x = L (f x) -- choice
| R (g x)
data (f :*: g) x = f x :&: g x -- pairing
instance Differentiable (K a) where
type D (K a) = K Void -- no children, so no way to make a hole
plug (K v, x) = absurd v -- can't reinvent the label, so deny the hole!
मैंने बाकी को हटाने का फैसला किया, भले ही यह बिल्कुल प्रासंगिक न हो।
instance Differentiable I where
type D I = K ()
plug (K (), x) = I x
instance (Differentiable f, Differentiable g) => Differentiable (f :+: g) where
type D (f :+: g) = D f :+: D g
plug (L df, x) = L (plug (df, x))
plug (R dg, x) = R (plug (dg, x))
instance (Differentiable f, Differentiable g) => Differentiable (f :*: g) where
type D (f :*: g) = (D f :*: g) :+: (f :*: D g)
plug (L (df :&: g), x) = plug (df, x) :&: g
plug (R (f :&: dg), x) = f :&: plug (dg, x)
दरअसल, शायद यह प्रासंगिक है। यदि आप रोमांच महसूस कर रहे हैं, तो यह अधूरा लेख दिखाता है कि Voidमुफ्त चर के साथ शब्दों के प्रतिनिधित्व को संपीड़ित करने के लिए कैसे उपयोग किया जाए
data Term f x = Var x | Con (f (Term f x)) -- the Free monad, yet again
किसी भी वाक्य रचना में एक Differentiableऔर Traversableफ़नकार से आज़ादी से उत्पन्न f। हम का उपयोग Term f Voidनहीं मुक्त चर के साथ क्षेत्रों का प्रतिनिधित्व करने के लिए, और [D f (Term f Void)]प्रतिनिधित्व करने के लिए ट्यूबों कोई मुफ्त चर या तो एक पृथक मुक्त चर करने के लिए, या दो या अधिक मुक्त चर के रास्तों में एक जंक्शन के साथ क्षेत्रों के माध्यम से सुरंग। उस लेख को कुछ समय समाप्त करना चाहिए।
एक प्रकार के लिए जिसमें कोई मान नहीं है (या कम से कम, विनम्र कंपनी में बोलने लायक नहीं है), Voidउल्लेखनीय रूप से उपयोगी है। और absurdआप इसका उपयोग कैसे करते हैं।
absurdइस लेख का उपयोग इस लेख में किया गया है जो किContमोनाद के साथ काम कर रहा है : haskellforall.com/2012/12/the-continuation-monad.html