पहली अच्छी बात यह है कि a -> b
map
का समर्थन कर सकता है। हां, फ़ंक्शंस फ़ैक्टर हैं!
के map
के प्रकार पर विचार करें:
map :: Functor f => (b -> c) -> f b -> f c
के Array
साथ Functor f => f
की जगह हमें एक ठोस प्रकार देने के लिए करते हैं:
map :: (b -> c) -> Maybe b -> Maybe c
:
map :: (b -> c) -> Array b -> Array c
के इस समय Maybe
साथ Functor f => f
की जगह चलो
सहसंबंध स्पष्ट है। के एक द्विआधारी प्रकार का परीक्षण करने के Either a
साथ Functor f => f
की जगह, करते हैं:
map :: (b -> c) -> Either a b -> Either a c
हम अक्सर b
a -> b
के रूप में a
से एक समारोह के प्रकार का प्रतिनिधित्व करते हैं, लेकिन वह वास्तव में सिर्फ Function a b
के लिए चीनी है। के Function
के साथ ऊपर हस्ताक्षर में लंबे फार्म का उपयोग करें और Either
की जगह दो:
map :: (b -> c) -> Function a b -> Function a c
तो, एक समारोह की मानचित्रण हमें एक समारोह जो मूल फ़ंक्शन द्वारा दिया गया मान पर b -> c
समारोह लागू होगी देता है।
map :: (b -> c) -> (a -> b) -> (a -> c)
सूचना कुछ भी: हम a -> b
चीनी का उपयोग कर हस्ताक्षर पुनर्लेखन सकता है? compose
का प्रकार क्या है?
compose :: (b -> c) -> (a -> b) -> a -> c
तो compose
सिर्फ map
समारोह प्रकार के विशेष है!
दूसरी अच्छी बात यह है कि a -> b
ap
का समर्थन कर सकते है। कार्य भी आवेदक मज़ेदार हैं! इन्हें काल्पनिक भूमि spec में Apply एस के रूप में जाना जाता है।
चलो ap
के प्रकार पर विचार करें:
ap :: Apply f => f (b -> c) -> f b -> f c
की जगह ले चलो Apply f => f
Array
साथ:
ap :: Array (b -> c) -> Array b -> Array c
अब
, Either a
साथ:
ap :: Either a (b -> c) -> Either a b -> Either a c
अब
, Function a
साथ:
ap :: Function a (b -> c) -> Function a b -> Function a c
Function a (b -> c)
क्या है? यह थोड़ा उलझन में है क्योंकि हम दो शैलियों को मिश्रित कर रहे हैं, लेकिन यह एक ऐसा फ़ंक्शन है जो a
प्रकार का मान लेता है और b
से c
पर एक फ़ंक्शन देता है। के a -> b
शैली का उपयोग पुनर्लेखन करते हैं:
ap :: (a -> b -> c) -> (a -> b) -> (a -> c)
किसी भी प्रकार की जो map
का समर्थन करता है और ap
"उठाया" जा सकता है। के lift2
पर एक नज़र लेते हैं:
lift2 :: Apply f => (b -> c -> d) -> f b -> f c -> f d
कि Function a
संतुष्ट याद रखें लागू की आवश्यकताओं, इसलिए हम जगह ले सकता है Apply f => f
Function a
साथ:
lift2 :: (b -> c -> d) -> Function a b -> Function a c -> Function a d
है कौन सा अधिक स्पष्ट रूप से लिखा:
lift2 :: (b -> c -> d) -> (a -> b) -> (a -> c) -> (a -> d)
चलिए अपनी प्रारंभिक अभिव्यक्ति पर फिर से जाएं:
// average :: Number -> Number
const average = lift2(divide, sum, length);
average([6, 7, 8])
क्या करता है? a
([6, 7, 8]
) a -> b
फ़ंक्शन (sum
) पर दिया गया है, b
(21
) का उत्पादन। a
भी a -> c
समारोह (length
) को दिया जाता है, एक c
(3
) का निर्माण किया। अब हमारे पास b
और c
है, हम उन्हें b -> c -> d
फ़ंक्शन (divide
) पर d
(7
) बनाने के लिए फ़ीड कर सकते हैं, जो अंतिम परिणाम है।
तो, क्योंकि समारोह प्रकार map
और ap
समर्थन कर सकते हैं, हम converge
किसी कीमत पर मिलता है (lift
, lift2
, और lift3
के माध्यम से)। मैं वास्तव में रामदा से converge
को हटाना चाहता हूं क्योंकि यह आवश्यक नहीं है।
नोट कि मैं जानबूझकर इस जवाब में R.lift
का उपयोग कर से बचा। किसी भी धर्मार्थ के कार्यों का समर्थन करने के फैसले के कारण इसका अर्थहीन प्रकार हस्ताक्षर और जटिल कार्यान्वयन है। दूसरी ओर अभयारण्य की धैर्य-विशिष्ट उठाने के कार्यों में स्पष्ट प्रकार के हस्ताक्षर और मामूली कार्यान्वयन होते हैं।
बहुत अच्छा! मुझे यह जवाब ब्लॉग पोस्ट में उठाए जाने को देखना अच्छा लगेगा! –
जब '(बी -> सी -> डी) -> (ए -> बी) -> (ए -> सी) -> (ए -> डी) 'को एक संयोजक के रूप में लागू किया गया है, यह' पक्षी = एफ = > जी => एच => एक्स => एफ (जी (एक्स)) (एच (एक्स)) '। यह 'psi = f => g => x => y => f (g (x)) (g (y)) के समान दिखता है। मुझे आश्चर्य है कि इस पक्षी का नाम कैसा है? – ftor
अपने स्वयं के प्रश्न का उत्तर देने के लिए: यह 'स्टार्लिंग' है, जो फ़ंक्शंस 'कॉन्स्ट एपी = एफ => जी => एक्स => एफ (एक्स) (जी (एक्स))' पर आवेदक के 'एपी' की संरचना है। रचना 'const comp = f => g => x => f (g (x)) ':' const starling_ = comp (comp (ap)) (comp) '। – ftor