लैंबडा शब्दों के लिए इस प्रतिनिधित्व पर विचार करें जो उनके मुक्त चर द्वारा पैराट्राइक किया गया है। (बेलीगार्ड और हुक 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