Haskell Language
एपेक्टिव फ़ंक्टर
खोज…
परिचय
Applicative
प्रकार के वर्ग है f :: * -> *
जो एक संरचना जहां समारोह भी है कि संरचना में अंतर्निहित है से अधिक समारोह आवेदन उठा लिया अनुमति देता है।
टिप्पणियों
परिभाषा
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
नोट Functor
पर बाधा f
। pure
समारोह अपने तर्क में एम्बेडेड रिटर्न Applicative
संरचना। इन्फ़िक्स समारोह <*>
(उच्चारण "लागू") बहुत के समान है fmap
समारोह में एम्बेडेड के साथ छोड़कर Applicative
संरचना।
का एक सही उदाहरण Applicative
हालांकि इन संकलक द्वारा लागू नहीं कर रहे हैं, अनुप्रयोगी कानूनों को पूरा करना चाहिए:
pure id <*> a = a -- identity
pure (.) <*> a <*> b <*> c = a <*> (b <*> c) -- composition
pure f <*> pure a = pure (f a) -- homomorphism
a <*> pure b = pure ($ b) <*> a -- interchange
वैकल्पिक परिभाषा
चूंकि हर अनुप्रयोगी functor एक है functor , fmap
हमेशा उस पर इस्तेमाल किया जा सकता; इस प्रकार लागू का सार सामग्री को जोड़ने, साथ ही इसे बनाने की क्षमता है:
class Functor f => PairingFunctor f where
funit :: f () -- create a context, carrying nothing of import
fpair :: (f a,f b) -> f (a,b) -- collapse a pair of contexts into a pair-carrying context
इस वर्ग के लिए है isomorphic Applicative
।
pure a = const a <$> funit = a <$ funit
fa <*> fb = (\(a,b) -> a b) <$> fpair (fa, fb) = uncurry ($) <$> fpair (fa, fb)
इसके विपरीत,
funit = pure ()
fpair (fa, fb) = (,) <$> fa <*> fb
आवेदन के सामान्य उदाहरण
शायद
Maybe
कि एक आवेदक फ़नकार है जिसमें संभवतः-अनुपस्थित मान हो।
instance Applicative Maybe where
pure = Just
Just f <*> Just x = Just $ f x
_ <*> _ = Nothing
pure
Just
इसे लागू करने से Maybe
दिए गए मूल्य को हटा देता है। (<*>)
समारोह एक समारोह एक में लिपटे लागू होता है Maybe
एक में एक मूल्य के लिए Maybe
। यदि फ़ंक्शन और मान दोनों मौजूद हैं ( Just
साथ निर्मित), फ़ंक्शन को मान पर लागू किया जाता है और लिपटे परिणाम वापस आ जाता है। यदि या तो लापता है, तो गणना आगे नहीं बढ़ सकती है और इसके बजाय Nothing
लौटाया जाता है।
सूचियाँ
सूचियों को टाइप करने के लिए एक तरीका है हस्ताक्षर <*> :: [a -> b] -> [a] -> [b]
दो सूचियों के कार्टेशियन उत्पाद को लेना है, प्रत्येक के साथ पहली सूची के प्रत्येक तत्व को जोड़ते हैं। दूसरे एक का तत्व:
fs <*> xs = [f x | f <- fs, x <- xs]
-- = do { f <- fs; x <- xs; return (f x) }
pure x = [x]
यह आमतौर पर नोंडेटर्मिनिज़्म का अनुकरण करने के रूप में व्याख्या की जाती है, एक मानदंड की एक सूची के लिए खड़े होते हैं, जिसका संभव मान उस सूची से अधिक होता है; इसलिए दो नोंडेटर्मिनिस्टिक मूल्यों का संयोजन दो सूचियों में मूल्यों के सभी संभावित संयोजनों पर निर्भर करता है:
ghci> [(+1),(+2)] <*> [3,30,300]
[4,31,301,5,32,302]
अनंत धाराएँ और ज़िप-सूचियाँ
वहाँ एक Applicative
जो अपने दो इनपुट एक साथ "ज़िप" का एक वर्ग है। एक सरल उदाहरण अनंत धाराओं का है:
data Stream a = Stream { headS :: a, tailS :: Stream a }
Stream
के Applicative
उदाहरण तर्क की एक धारा के लिहाज से बात करने के लिए कार्यों की एक धारा लागू होता है, स्थिति से दो धाराओं गए मानों को युग्मन हो जाएगा। pure
रिटर्न एक निरंतर स्ट्रीम - एकल निश्चित मान की एक अनंत सूची:
instance Applicative Stream where
pure x = let s = Stream x s in s
Stream f fs <*> Stream x xs = Stream (f x) (fs <*> xs)
सूचियाँ भी एक "त्वरित संदर्भ" स्वीकार Applicative
उदाहरण है, जिसके लिए वहां मौजूद ZipList
newtype:
newtype ZipList a = ZipList { getZipList :: [a] }
instance Applicative ZipList where
ZipList xs <*> ZipList ys = ZipList $ zipWith ($) xs ys
चूंकि zip
कम से कम इनपुट, का ही कार्यान्वयन के अनुसार उसके परिणाम ट्रिम pure
कि संतुष्ट Applicative
कानून है जो एक अनंत सूची लौटाती है:
pure a = ZipList (repeat a) -- ZipList (fix (a:)) = ZipList [a,a,a,a,...
उदाहरण के लिए:
ghci> getZipList $ ZipList [(+1),(+2)] <*> ZipList [3,30,300]
[4,32]
दो संभावनाएं हमें बाहरी और आंतरिक उत्पाद की याद दिलाती हैं, पहले मामले में 1-पंक्ति ( 1 xm
) एक के साथ 1-कॉलम ( nx 1
) मैट्रिक्स को गुणा करने के समान है, परिणामस्वरूप nxm
मैट्रिक्स प्राप्त करना (लेकिन चपटा हुआ) ); या दूसरे मामले में 1-पंक्ति और 1-कॉलम मैट्रिसेस (लेकिन बिना संक्षेप के) को गुणा करना।
कार्य
कार्यों के लिए विशेष जब (->) r
, के प्रकार के हस्ताक्षर pure
और <*>
के मिलान में K
और S
combinators क्रमश:
pure :: a -> (r -> a)
<*> :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
pure
const
होना चाहिए, और <*>
कार्यों की एक जोड़ी लेता है और प्रत्येक को एक निश्चित तर्क पर लागू करता है, दो परिणामों को लागू करता है:
instance Applicative ((->) r) where
pure = const
f <*> g = \x -> f x (g x)
फ़ंक्शंस प्रोटोटाइपिक "ज़िप्पी" अनुप्रयोग हैं। उदाहरण के लिए, चूंकि अनंत धाराएँ (->) Nat
, के लिए (->) Nat
...
-- | Index into a stream
to :: Stream a -> (Nat -> a)
to (Stream x xs) Zero = x
to (Stream x xs) (Suc n) = to xs n
-- | List all the return values of the function in order
from :: (Nat -> a) -> Stream a
from f = from' Zero
where from' n = Stream (f n) (from' (Suc n))
... एक उच्च क्रम रास्ते में धाराओं का प्रतिनिधित्व त्वरित संदर्भ का उत्पादन Applicative
उदाहरण स्वचालित रूप से।