Haskell Language
functor
खोज…
परिचय
Functor
, प्रकारों की श्रेणी है f :: * -> *
जिस पर covariantly मैप किया जा सकता है। एक डेटा संरचना पर एक फ़ंक्शन का मानचित्रण, संरचना को बदलने के बिना संरचना के सभी तत्वों पर फ़ंक्शन को लागू करता है।
टिप्पणियों
एक फ़नकार को कुछ मूल्य के लिए एक कंटेनर के रूप में माना जा सकता है, या एक गणना संदर्भ। उदाहरण Maybe a
या [a]
। टाइपराइक्लोपीडिया लेख में फ़नसर्स के पीछे की अवधारणाओं का अच्छा लेखन है।
एक वास्तविक फ़नकार माना जाने के लिए, एक उदाहरण के लिए 2 निम्नलिखित कानूनों का सम्मान करना होगा:
पहचान
fmap id == id
रचना
fmap (f . g) = (fmap f) . (fmap g)
फनकार के सामान्य उदाहरण
शायद
Maybe
एक Functor
जिसमें संभवतः-अनुपस्थित मान होता है:
instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
Maybe
Functor
उदाहरण एक फ़ंक्शन को Just
एक लिपटे मान पर लागू होता है। यदि गणना पहले विफल हो गई है (इसलिए Maybe
मान Nothing
), तो फ़ंक्शन को लागू करने के लिए कोई मूल्य नहीं है, इसलिए fmap
एक नो-ऑप है।
> fmap (+ 3) (Just 3)
Just 6
> fmap length (Just "mousetrap")
Just 9
> fmap sqrt Nothing
Nothing
हम इस तर्क के लिए फ़ंक्शनल कानूनों की जाँच कर सकते हैं। पहचान कानून के लिए,
fmap id Nothing
Nothing -- definition of fmap
id Nothing -- definition of id
fmap id (Just x)
Just (id x) -- definition of fmap
Just x -- definition of id
id (Just x) -- definition of id
रचना कानून के लिए,
(fmap f . fmap g) Nothing
fmap f (fmap g Nothing) -- definition of (.)
fmap f Nothing -- definition of fmap
Nothing -- definition of fmap
fmap (f . g) Nothing -- because Nothing = fmap f Nothing, for all f
(fmap f . fmap g) (Just x)
fmap f (fmap g (Just x)) -- definition of (.)
fmap f (Just (g x)) -- definition of fmap
Just (f (g x)) -- definition of fmap
Just ((f . g) x) -- definition of (.)
fmap (f . g) (Just x) -- definition of fmap
सूचियाँ
Functor
की सूची उदाहरण जगह में सूची में हर मूल्य पर फ़ंक्शन को लागू करता है।
instance Functor [] where
fmap f [] = []
fmap f (x:xs) = f x : fmap f xs
इसे वैकल्पिक रूप से एक सूची समझ के रूप में लिखा जा सकता है: fmap f xs = [fx | x <- xs]
।
इस उदाहरण से पता चलता है कि map
सामान्य fmap
है। map
केवल सूचियों पर चल रही है, जबकि fmap
एक मनमाना पर काम करता है Functor
।
पहचान कानून को शामिल करने के लिए दिखाया जा सकता है:
-- base case
fmap id []
[] -- definition of fmap
id [] -- definition of id
-- inductive step
fmap id (x:xs)
id x : fmap id xs -- definition of fmap
x : fmap id xs -- definition of id
x : id xs -- by the inductive hypothesis
x : xs -- definition of id
id (x : xs) -- definition of id
और इसी तरह, संरचना कानून:
-- base case
(fmap f . fmap g) []
fmap f (fmap g []) -- definition of (.)
fmap f [] -- definition of fmap
[] -- definition of fmap
fmap (f . g) [] -- because [] = fmap f [], for all f
-- inductive step
(fmap f . fmap g) (x:xs)
fmap f (fmap g (x:xs)) -- definition of (.)
fmap f (g x : fmap g xs) -- definition of fmap
f (g x) : fmap f (fmap g xs) -- definition of fmap
(f . g) x : fmap f (fmap g xs) -- definition of (.)
(f . g) x : fmap (f . g) xs -- by the inductive hypothesis
fmap (f . g) xs -- definition of fmap
कार्य
हर Functor
कंटेनर की तरह नहीं दिखता है। Functor
फ़ंक्शंस का उदाहरण दूसरे फ़ंक्शन के रिटर्न वैल्यू पर एक फ़ंक्शन लागू करता है।
instance Functor ((->) r) where
fmap f g = \x -> f (g x)
ध्यान दें कि यह परिभाषा fmap = (.)
बराबर है। इसलिए fmap
सामान्य रूप से कार्य रचना करता है।
एक बार पहचान कानून की जाँच करने के बाद:
fmap id g
\x -> id (g x) -- definition of fmap
\x -> g x -- definition of id
g -- eta-reduction
id g -- definition of id
और रचना कानून:
(fmap f . fmap g) h
fmap f (fmap g h) -- definition of (.)
fmap f (\x -> g (h x)) -- definition of fmap
\y -> f ((\x -> g (h x)) y) -- definition of fmap
\y -> f (g (h y)) -- beta-reduction
\y -> (f . g) (h y) -- definition of (.)
fmap (f . g) h -- definition of fmap
फनकार और कानून की कक्षा परिभाषा
class Functor f where
fmap :: (a -> b) -> f a -> f b
इसे देखने का एक तरीका यह है कि fmap
मानों के एक फ़ंक्शन को संदर्भ f
में मानों के एक फ़ंक्शन में लिफ्ट करता है।
Functor
का एक सही उदाहरण Functor
कानूनों को संतुष्ट करना चाहिए, हालांकि ये संकलक द्वारा लागू नहीं किए जाते हैं:
fmap id = id -- identity
fmap f . fmap g = fmap (f . g) -- composition
fmap
लिए आमतौर पर उपयोग किया जाने वाला infix उपनाम है <$>
।
infixl 4 <$>
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$>) = fmap
फ़नकार के सभी तत्वों को एक ही मान से प्रतिस्थापित करना
Data.Functor
मॉड्यूल में दो कॉम्बिनेटर शामिल होते हैं, <$
और $>
, जो एक फ़ाइटर में निहित सभी मानों को अनदेखा करते हैं, उन सभी को एक ही निरंतर मान के साथ प्रतिस्थापित करते हैं।
infixl 4 <$, $>
<$ :: Functor f => a -> f b -> f a
(<$) = fmap . const
$> :: Functor f => f a -> b -> f b
($>) = flip (<$)
void
एक संगणना के रिटर्न मान को अनदेखा करता है।
void :: Functor f => f a -> f ()
void = (() <$)
बहुपद विन्यासकर्ता
छोटे लोगों के लिए बड़े Functor
निर्माण के लिए एक प्रकार का कॉम्बिनेटर है। ये Functor
उदाहरण उदाहरण के रूप में शिक्षाप्रद हैं, और वे सामान्य प्रोग्रामिंग के लिए एक तकनीक के रूप में भी उपयोगी हैं, क्योंकि उनका उपयोग सामान्य फ़ंक्शंसर्स के एक बड़े वर्ग का प्रतिनिधित्व करने के लिए किया जा सकता है।
पहचान फ़नकार
पहचान फ़नकार बस अपने तर्क को लपेटता है। यह SKI पथरी से I
कॉम्बीनेटर का एक प्रकार-स्तरीय कार्यान्वयन है।
newtype I a = I a
instance Functor I where
fmap f (I x) = I (f x)
I
Data.Functor.Identity
मॉड्यूल में Identity
के नाम से पाया जा सकता है।
निरंतर फ़नकार
निरंतर फ़नकार अपने दूसरे तर्क की उपेक्षा करता है, जिसमें केवल एक स्थिर मान होता है। यह const
का एक प्रकार-स्तरीय एनालॉग है, SKI पथरी से K
कॉम्बिनेटर है।
newtype K c a = K c
ध्यान दें कि K ca
कुछ भी नहीं है a
-values; K ()
Proxy
लिए आइसोमोर्फिक है। इसका मतलब है कि K
के के कार्यान्वयन fmap
सब पर किसी भी मानचित्रण नहीं करता है!
instance Functor (K c) where
fmap _ (K c) = K c
K
को अन्यथा Data.Functor.Const
से Const
रूप में जाना जाता है।
इस उदाहरण में शेष फंक्शनालर्स छोटे फंक्शनालर्स को बड़े में मिलाते हैं।
फ़नकार उत्पाद
फ़ंक्शनल उत्पाद फंक्शनलर्स की एक जोड़ी लेता है और उन्हें पैक करता है। यह टपल के अनुरूप है, जबकि इसके अलावा (,) :: * -> * -> *
जबकि (,) :: * -> * -> *
types
पर संचालित होता है *
, (:*:) :: (* -> *) -> (* -> *) -> (* -> *)
functors
पर संचालित होता है * -> *
।
infixl 7 :*:
data (f :*: g) a = f a :*: g a
instance (Functor f, Functor g) => Functor (f :*: g) where
fmap f (fx :*: gy) = fmap f fx :*: fmap f gy
यह प्रकार, Data.Functor.Product
मॉड्यूल में Product
नाम के तहत पाया जा सकता है।
फन कॉपोरेटर
जैसे :*:
के अनुरूप है (,)
:+:
Either
संस्कार स्तर एनालॉग है।
infixl 6 :+:
data (f :+: g) a = InL (f a) | InR (g a)
instance (Functor f, Functor g) => Functor (f :+: g) where
fmap f (InL fx) = InL (fmap f fx)
fmap f (InR gy) = InR (fmap f gy)
:+:
Data.Functor.Sum
मॉड्यूल में Sum
नाम के तहत पाया जा सकता है।
फनकार रचना
अंत में :.:
एक टाइप-लेवल (.)
तरह काम करता है, एक फ़नकार का आउटपुट लेता है और उसे दूसरे के इनपुट में प्लंबिंग करता है।
infixr 9 :.:
newtype (f :.: g) a = Cmp (f (g a))
instance (Functor f, Functor g) => Functor (f :.: g) where
fmap f (Cmp fgx) = Cmp (fmap (fmap f) fgx)
Compose
प्रकार Data.Functor.Compose
में पाया जा सकता है
जेनेरिक प्रोग्रामिंग के लिए बहुपद फंक्शंस
I
, K
, :*:
, :+:
और :.:
सरल डेटाटाइप्स की एक निश्चित वर्ग के लिए ब्लॉक के निर्माण की एक किट के रूप में के बारे में सोचा जा सकता है। जब आप इसे निश्चित बिंदुओं के साथ जोड़ते हैं तो किट विशेष रूप से शक्तिशाली हो जाती है क्योंकि इन कॉम्बिनेटरों के साथ निर्मित डेटाटाइप्स स्वचालित रूप से Functor
उदाहरण हैं। आप एक टेम्पलेट प्रकार बनाने के लिए किट का उपयोग करते हैं, I
का उपयोग करके पुनरावर्ती बिंदुओं को चिह्नित करते हैं, और फिर इसे एक प्रकार प्राप्त करने के लिए Fix
में प्लग करते हैं जो पुनरावृत्ति योजनाओं के मानक चिड़ियाघर के साथ उपयोग किया जा सकता है।
नाम | एक डेटाटाइप के रूप में | फफूंद किट का उपयोग करना |
---|---|---|
मूल्यों के जोड़े | data Pair a = Pair aa | type Pair = I :*: I |
दो-दो-दो ग्रिड | type Grid a = Pair (Pair a) | type Grid = Pair :.: Pair |
प्राकृतिक संख्याएं | data Nat = Zero | Succ Nat | type Nat = Fix (K () :+: I) |
सूचियाँ | data List a = Nil | Cons a (List a) | type List a = Fix (K () :+: K a :*: I) |
बाइनरी ट्री | data Tree a = Leaf | Node (Tree a) a (Tree a) | type Tree a = Fix (K () :+: I :*: K a :*: I) |
गुलाब के पेड़ | data Rose a = Rose a (List (Rose a)) | type Rose a = Fix (K a :*: List :.: I) |
डेटाटाइप्स को डिजाइन करने के लिए यह "किट" दृष्टिकोण generics-sop
जैसे सामान्य प्रोग्रामिंग पुस्तकालयों के पीछे का विचार है। यह विचार है कि ऊपर प्रस्तुत की गई किट की तरह जेनेरिक संचालन को लिखना है, और फिर उनके जेनेरिक प्रतिनिधित्व से और मनमाने ढंग से डेटाटाइप्स में परिवर्तित करने के लिए एक प्रकार की कक्षा का उपयोग करें:
class Generic a where
type Rep a -- a generic representation built using a kit
to :: a -> Rep a
from :: Rep a -> a
श्रेणी सिद्धांत में फ़नकार
एक फ़ंक्टर को श्रेणी के बीच संरचना-संरक्षण मानचित्र ('होमोमोर्फिज़्म') के रूप में श्रेणी सिद्धांत में परिभाषित किया गया है। विशेष रूप से, (सभी) वस्तुओं को वस्तुओं के लिए मैप किया जाता है, और (सभी) तीर को तीर से मैप किया जाता है, जैसे कि श्रेणी के कानून संरक्षित हैं।
वह श्रेणी जिसमें ऑब्जेक्ट हास्केल प्रकार के होते हैं और आकारिकी हैं हास्केल फ़ंक्शन को हास्क कहा जाता है। तो हास्क से हास्क तक का एक फ़नकार , प्रकारों के मानचित्रण और फ़ंक्शंस से फ़ंक्शंस की मैपिंग से मिलकर बना होगा।
संबंध जो इस श्रेणी की थ्योरीटिक अवधारणा हैस्केल प्रोग्रामिंग कंस्ट्रक्शन Functor
है, बल्कि प्रत्यक्ष है। प्रकारों से प्रकारों की मैपिंग एक प्रकार का रूप लेती है f :: * -> *
, और फ़ंक्शंस से फ़ंक्शंस के लिए मैपिंग एक फ़ंक्शन का रूप fmap :: (a -> b) -> (fa -> fb)
। उन लोगों को एक कक्षा में एक साथ रखकर,
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
fmap
एक ऐसा ऑपरेशन है जो एक फंक्शन (एक प्रकार का रूपवाद) लेता है, :: a -> b
, और इसे दूसरे फंक्शन में ले जाता है, :: fa -> fb
। यह माना जाता है (लेकिन प्रोग्रामर सुनिश्चित करने के लिए छोड़ दिया) कि के उदाहरण है Functor
वास्तव में गणितीय functors, Hask की स्पष्ट संरचना के संरक्षण कर रहे हैं:
fmap (id {- :: a -> a -}) == id {- :: f a -> f a -}
fmap (h . g) == fmap h . fmap g
fmap
एक फ़ंक्शन :: a -> b
को हास्क की उपश्रेणी में एक तरह से शामिल किया, जो किसी भी पहचान के तीर के अस्तित्व और रचना की संबद्धता दोनों को संरक्षित करता है।
Functor
वर्ग केवल encodes Hask पर functors एंडो। लेकिन गणित में, फंक्शनलर्स मनमानी श्रेणियों के बीच मैप कर सकते हैं। इस अवधारणा का एक अधिक वफादार एन्कोडिंग इस तरह दिखेगा:
class Category c where
id :: c i i
(.) :: c j k -> c i j -> c i k
class (Category c1, Category c2) => CFunctor c1 c2 f where
cfmap :: c1 a b -> c2 (f a) (f b)
मानक फनकार वर्ग इस वर्ग का एक विशेष मामला है जिसमें स्रोत और लक्ष्य श्रेणियां दोनों हास्क हैं । उदाहरण के लिए,
instance Category (->) where -- Hask
id = \x -> x
f . g = \x -> f (g x)
instance CFunctor (->) (->) [] where
cfmap = fmap
व्युत्पन्न फ़नकार
DeriveFunctor
भाषा विस्तार GHC के उदाहरण उत्पन्न करने के लिए अनुमति देता है Functor
स्वचालित रूप से।
{-# LANGUAGE DeriveFunctor #-}
data List a = Nil | Cons a (List a) deriving Functor
-- instance Functor List where -- automatically defined
-- fmap f Nil = Nil
-- fmap f (Cons x xs) = Cons (f x) (fmap f xs)
map :: (a -> b) -> List a -> List b
map = fmap