क्या सभी निश्चित आकार के कंटेनर मजबूत मोनोएडल फंक्शनलर्स, और / या इसके विपरीत हैं?


9

ApplicativeTypeclass का प्रतिनिधित्व करता है ढीला monoidal functors कि आपके द्वारा लिखे गए कार्यों की श्रेणी पर कार्तीय monoidal संरचना की रक्षा।

दूसरे शब्दों में, (,)एक सांध्यात्मक संरचना को देखते हुए विहित आइसोमोर्फिम्स दिए गए हैं :

-- Implementations left to the motivated reader
assoc_fwd :: ((a, b), c) -> (a, (b, c))
assoc_bwd :: (a, (b, c)) -> ((a, b), c)

lunit_fwd :: ((), a) -> a
lunit_bwd :: a -> ((), a)

runit_fwd :: (a, ()) -> a
runit_bwd :: a -> (a, ())

टाइपकास्ट और इसके कानून को इस तरह लिखा जा सकता है:

class Functor f => Applicative f
  where
  zip :: (f a, f b) -> f (a, b)
  husk :: () -> f ()

-- Laws:

-- assoc_fwd >>> bimap id zip >>> zip
-- =
-- bimap zip id >>> zip >>> fmap assoc_fwd

-- lunit_fwd
-- =
-- bimap husk id >>> zip >>> fmap lunit_fwd

-- runit_fwd
-- =
-- bimap id husk >>> zip >>> fmap runit_fwd

कोई भी आश्चर्यचकित हो सकता है कि एक फंक्शनल जो कि एक ही संरचना के संबंध में ओपलैक्स मोनोइडल है, वह कैसा दिख सकता है:

class Functor f => OpApplicative f
  where
  unzip :: f (a, b) -> (f a, f b)
  unhusk :: f () -> ()

-- Laws:

-- assoc_bwd <<< bimap id unzip <<< unzip
-- =
-- bimap unzip id <<< unzip <<< fmap assoc_bwd

-- lunit_bwd
-- =
-- bimap unhusk id <<< unzip <<< fmap lunit_bwd

-- runit_bwd
-- =
-- bimap id unhusk <<< unzip <<< fmap runit_bwd

यदि हम परिभाषाओं और कानूनों में शामिल प्रकारों के बारे में सोचते हैं, तो निराशाजनक सच्चाई सामने आती है; OpApplicativeइससे अधिक विशिष्ट कोई बाधा नहीं है Functor:

instance Functor f => OpApplicative f
  where
  unzip fab = (fst <$> fab, snd <$> fab)
  unhusk = const ()

हालांकि, जबकि हर Applicativeफनकार (वास्तव में, कोई भी Functor) तुच्छ है OpApplicative, जरूरी नहीं कि जुलाब Applicativeऔर OpApplicativeअपारदर्शी के बीच एक अच्छा संबंध हो । तो हम मजबूत monoidal फंक्शनल के लिए देख सकते हैं कार्टेशियन monoidal संरचना wrt:

class (Applicative f, OpApplicative f) => StrongApplicative f

-- Laws:
-- unhusk . husk = id
-- husk . unhusk = id
-- zip . unzip = id
-- unzip . zip = id

उपरोक्त पहला कानून तुच्छ है, क्योंकि एकमात्र प्रकार () -> ()का निवासी पहचान समारोह है ()

हालांकि, शेष तीन कानून, और इसलिए उपवर्ग ही, तुच्छ नहीं है। विशेष रूप से, प्रत्येक Applicativeइस वर्ग का वैध उदाहरण नहीं है।

यहां कुछ Applicativeफ़ंक्शंस हैं, जिनके लिए हम वैध उदाहरणों की घोषणा कर सकते हैं StrongApplicative:

  • Identity
  • VoidF
  • (->) r
  • Monoid m => (,) m (उत्तर देखें)
  • Vec (n :: Nat)
  • Stream (अनंत)

और यहाँ कुछ Applicativeएस हैं जिनके लिए हम नहीं कर सकते हैं:

  • []
  • Either e
  • Maybe
  • NonEmptyList

यहाँ पैटर्न से पता चलता है कि StrongApplicativeकक्षा एक अर्थ में है FixedSize, जहाँ "निश्चित आकार" * का अर्थ है कि एक निवासी के निवासियों की बहुलता ** निर्धारित है।af a

यह दो अनुमानों के रूप में कहा जा सकता है:

  • हर Applicativeअपने प्रकार तर्क के तत्वों में से एक "स्थिर आकार" कंटेनर का प्रतिनिधित्व करने का एक उदाहरण हैStrongApplicative
  • ऐसा कोई उदाहरण StrongApplicativeमौजूद नहीं है जिसमें घटनाओं की संख्या aभिन्न हो सकती है

क्या कोई भी ऐसे संदर्भों के बारे में सोच सकता है जो इन अनुमानों को खारिज करते हैं, या कुछ ठोस तर्क जो यह प्रदर्शित करते हैं कि वे सच्चे या झूठे क्यों हैं?


* मुझे एहसास है कि मैंने विशेषण "निश्चित आकार" को ठीक से परिभाषित नहीं किया है। दुर्भाग्य से कार्य थोड़ा सा गोलाकार है। मुझे "निश्चित आकार" कंटेनर के किसी भी औपचारिक विवरण का पता नहीं है, और मैं एक के साथ आने की कोशिश कर रहा हूं। StrongApplicativeमेरी अब तक की सबसे अच्छी कोशिश है।

मूल्यांकन करने के लिए कि क्या यह एक अच्छी परिभाषा है, हालांकि, मुझे इसकी तुलना करने के लिए कुछ चाहिए। किसी प्रकार के फ़नकार के लिए कुछ औपचारिक / अनौपचारिक परिभाषा को देखते हुए, उसके प्रकार के तर्क के निवासियों के संबंध में किसी दिए गए आकार या गुणन के लिए इसका मतलब है, सवाल यह है कि क्या एक StrongApplicativeउदाहरण का अस्तित्व निश्चित रूप से निश्चित और भिन्न आकार के फंक्शंस को अलग करता है।

मौजूदा औपचारिक परिभाषा से अवगत नहीं होने के कारण, मैं "निश्चित आकार" शब्द के उपयोग में अंतर्ज्ञान की अपील कर रहा हूं। हालांकि अगर किसी को पहले से ही एक फ़न्क्टर के आकार के लिए एक औपचारिक औपचारिकता का पता है और वह इसकी तुलना StrongApplicativeकर सकता है, तो बेहतर है।

** "गुणन" के द्वारा मैं फफूंद के पैरामीटर प्रकार के "ढीले अर्थ" का जिक्र करता हूं, जो कि फंटर के पैरामीटर प्रकार के अनियंत्रित तत्व फंकीर के कोडोमैन प्रकार के निवासियों में होते हैं। यह विशिष्ट प्रकार के संबंध के बिना है जिस पर फ़नकार को लागू किया जाता है, और इसलिए पैरामीटर प्रकार के किसी भी विशिष्ट निवासियों के संबंध के बिना।

इसके बारे में सटीक नहीं होने के कारण टिप्पणियों में कुछ भ्रम पैदा हो गया है, इसलिए यहां कुछ उदाहरणों के बारे में कुछ उदाहरण प्रस्तुत करूंगा, जो कि विभिन्न प्रकारों के आकार / गुणन को मानते हैं:

  • VoidF: नियत, ०
  • Identity: नियत, १
  • Maybe: चर, न्यूनतम ०, अधिकतम १
  • []: चर, न्यूनतम 0, अधिकतम अनंत
  • NonEmptyList: चर, न्यूनतम 1, अधिकतम अनंत
  • Stream: निश्चित, अनंत
  • Monoid m => (,) m: नियत, १
  • data Pair a = Pair a a: नियत, २
  • Either x: चर, न्यूनतम ०, अधिकतम १
  • data Strange a = L a | R a: नियत, १

टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
शमूएल ल्यू

"निश्चित आकार" की एक संभावित परिभाषा "प्रतिनिधित्व करने योग्य" होगी। सभी अभिप्रेरित फ़ंक्शंसर्स यहां वर्णित अर्थों में मजबूत अनुप्रयोग हैं, क्योंकि (->) rवे सही तरीके से आइसोमॉर्फिक हैं।
डैनियल वैगनर

@DanielWagner मुझे लगता है कि आपको मजबूत आवेदन से विरासत में लेने के लिए सिर्फ एक समरूपता से अधिक की आवश्यकता है (->) r; आपको मजबूत एपेरेटिव संरचना को संरक्षित करने के लिए आइसोमोर्फिज्म के घटकों की आवश्यकता होती है। किसी कारण के लिए Representableहास्केल में टाइपकास्ट में एक रहस्यमय tabulate . return = returnकानून है (जो वास्तव में गैर राक्षसी फंक्शंस के लिए भी समझ में नहीं आता है), लेकिन यह हमें उन परिस्थितियों का 1/4 हिस्सा देता है जो हमें कहने की आवश्यकता है tabulateऔर zipएक उपयुक्त श्रेणी के मोनोरेड के रूप हैं । अन्य 3 आपके लिए अतिरिक्त कानून हैं।
असद सईदुद्दीन

क्षमा करें, यह होना चाहिए " tabulateऔर indexएक उपयुक्त श्रेणी के आकारिकी हैं ..."
असद सईदुद्दीन

@AsadSaeeduddin डॉक्स में कानून को जिस तरह से कहा गया है, वह विचित्र रूप से विशिष्ट है, शायद, लेकिन यह पता चला है कि आवश्यकता returnनहीं है एक गंभीर समस्या है। / के संदर्भ में / के cotraverse getConst . Constलिए एक डिफ़ॉल्ट कार्यान्वयन है , क्योंकि वितरण / निरूपण के लिए निश्चित आकार है, कि कार्यान्वयन अद्वितीय है। returnpureDistributive
डुप्लोड

जवाबों:


4
  • हर Applicativeअपने प्रकार तर्क के तत्वों में से एक "स्थिर आकार" कंटेनर का प्रतिनिधित्व करने का एक उदाहरण हैStrongApplicative
  • ऐसा कोई उदाहरण StrongApplicativeमौजूद नहीं है जिसमें घटनाओं की संख्या aभिन्न हो सकती है

क्या कोई भी ऐसे संदर्भों के बारे में सोच सकता है जो इन अनुमानों को खारिज करते हैं, या कुछ ठोस तर्क जो यह प्रदर्शित करते हैं कि वे सच्चे या झूठे क्यों हैं?

मुझे उस पहले अनुमान के बारे में यकीन नहीं है, और @AsadSaeeduddin के साथ चर्चा के आधार पर इसे साबित करना मुश्किल हो सकता है, लेकिन दूसरा अनुमान सच है। क्यों देखें, StrongApplicativeकानून पर विचार करें husk . unhusk == id; है कि सभी के लिए, है x :: f (), husk (unhusk x) == x। लेकिन हास्केल में, unhusk == const ()तो यह है कि कानून सभी के लिए कह रही है के बराबर है x :: f (), husk () == x। लेकिन यह बदले में तात्पर्य है कि केवल एक ही प्रकार का एक अलग मूल्य हो सकता है f (): यदि दो मूल्य थे x, y :: f (), तो x == husk ()और husk () == y, इसलिए x == y। लेकिन अगर केवल एक ही संभव f ()मूल्य है, तो fनिश्चित आकार का होना चाहिए। (उदाहरण के लिए data Pair a = Pair a a, वहाँ प्रकार का केवल एक मूल्य है Pair (), इस से किया जा रहा Pair () ()है, लेकिन के प्रकार के एक से अधिक मान रहे हैंMaybe () या [()]।) इस प्रकारhusk . unhusk == idतात्पर्य है कि fनिश्चित आकार का होना चाहिए।


हम्म। क्या यह वास्तव में स्पष्ट है कि " फैंसी जीएडीटी और सामान की उपस्थिति में" केवल एक ही प्रकार के अलग-अलग मूल्य नहीं हो सकते हैं " f ()की घटना aघट सकती है"?
डैनियल वैगनर

@DanielWagner यह पता चला कि "घटनाओं की संख्या aभिन्न नहीं हो सकती है" StrongApplicativeउदाहरण के लिए पर्याप्त स्थिति नहीं है ; उदाहरण के लिए, data Writer w a = Writer (w,a)की गैर-अलग-अलग बहुलता है a, लेकिन नहीं है StrongApplicative। आपको वास्तव में फनकार के आकार की आवश्यकता होती है, जो अपरिवर्तनीय है, जो मुझे लगता है कि f ()एक सिंगलटन होने का एक परिणाम है ।
bradrn

मुझे यकीन नहीं है कि मैं देख रहा हूं कि यह कैसे प्रासंगिक है। उत्तर में, दूसरे अनुमान की पुष्टि करते हुए, आप तर्क देते हैं कि "मजबूत आवेदक" का अर्थ है "एक अलग f ()" का तात्पर्य " aभिन्न होने की संख्या " भिन्न नहीं हो सकता है। मुझे आपत्ति है कि उस तर्क का अंतिम चरण स्पष्ट रूप से सच नहीं है; जैसे विचार करें data Weird a where One :: a -> Weird a; None :: Weird Bool। प्रकार का एक अलग मूल्य होता है Weird (), लेकिन अलग-अलग निर्माणकर्ताओं की संख्या अलग-अलग होती aहै। (यह यहाँ पूर्ण प्रतिपक्ष नहीं है क्योंकि Functorकठिन है, लेकिन हम कैसे जानते हैं कि इसे ठीक नहीं किया जा सकता है?)
डैनियल वैगनर

@DanielWagner गुड पॉइंट जो Weird ()एक सिंगलटन है लेकिन यह निश्चित आकार का नहीं है। लेकिन Weirdयह नहीं है Functor, इसलिए यह StrongApplicativeवैसे भी नहीं हो सकता । मुझे लगता है कि प्रासंगिक अनुमान होगा: यदि fFunctor, f ()एक सिंगलटन होने का मतलब है कि fनिश्चित आकार का है ? मुझे यह सच होने पर बहुत संदेह है, लेकिन जैसा कि आपने उल्लेख किया है कि मेरे पास वास्तव में अभी तक कोई प्रमाण नहीं है।
2:10 बजे

5

हम इनमें से कम से कम एक प्रश्न का उत्तर नकारात्मक में दे सकते हैं:

अपने प्रकार के तर्क के तत्वों के एक "निश्चित आकार" कंटेनर का प्रतिनिधित्व करने वाला प्रत्येक आवेदक स्ट्रांगऐप्लिकेटिव का एक उदाहरण है

वास्तव StrongApplicativeमें मूल प्रश्न में एक वैध का एक उदाहरण गलत है। उदाहरण के लिए लेखक आवेदनकर्ता Monoid => (,) mनहीं है ।StrongApplicativehusk $ unhusk $ ("foo", ()) == ("", ()) /= ("foo", ())

इसी तरह, एक निश्चित आकार के कंटेनर का उदाहरण:

data Strange a = L a | R a

तय बहुलता 1 की, एक मजबूत अनुप्रयोगी, क्योंकि यदि हम परिभाषित नहीं है husk = Leftतो husk $ unhusk $ Right () /= Right ()विपरीत है, और इसके। इसे देखने का एक समान तरीका यह है कि यह आपकी पसंद के लिए लेखक का केवल आवेदन है Bool

तो वहाँ "निश्चित आकार" वाले आवेदन मौजूद हैं जो नहीं हैं StrongApplicative। क्या सभी StrongApplicativeनिश्चित आकार के हैं, देखा जाना चाहिए।


5

चलो "निश्चित आकार कंटेनर" की हमारी परिभाषा के रूप में प्रतिनिधित्व करने योग्य फंक्शंस लेते हैं:

class Representable f where
    type Rep f
    tabulate :: (Rep f -> a) -> f a
    index :: f a -> Rep f -> a

वास्तविक के Representableपास कुछ कानून और सुपरक्लास हैं, लेकिन इस उत्तर के प्रयोजनों के लिए, हमें वास्तव में सिर्फ दो गुणों की आवश्यकता है:

tabulate . index = id
index . tabulate = id

(ठीक है, हमें कानून-पालन की भी आवश्यकता है instance StrongApplicative ((->) r)। आसान मटर, आप पहले से ही सहमत हैं कि यह मौजूद है।)

यदि हम वह परिभाषा लेते हैं, तो मैं उस अनुमान की पुष्टि कर सकता हूं 1:

Applicativeअपने प्रकार के तर्क के तत्वों के "निश्चित आकार" कंटेनर का प्रतिनिधित्व करने वाला प्रत्येक एक [कानून-पालन करने वाला] उदाहरण हैStrongApplicative

सच हैं। ऐसे:

instance Representable f => Applicative f where
    zip (fa, fb) = tabulate (zip (index fa, index fb))
    husk = tabulate . husk

instance Representable f => OpApplicative f where
    unzip fab = let (fa, fb) = unzip (index fab) in (tabulate fa, tabulate fb)
    unhusk = unhusk . index

instance Representable f => StrongApplicative f

साबित करने के लिए बहुत सारे कानून हैं, लेकिन मैं सिर्फ बिग फोर पर ध्यान केंद्रित करूंगा जो StrongApplicativeजोड़ देगा - आप शायद पहले से ही लीड-इन के लिए विश्वास करते हैं Applicativeऔर OpApplicative, लेकिन यदि आप नहीं करते हैं, तो उनके प्रमाण नीचे दिए गए लोगों की तरह दिखते हैं ( जो बदले में एक दूसरे की तरह काफी दिखते हैं)। स्पष्टता के लिए, मैं का उपयोग करेगा zipf, huskfसमारोह उदाहरण के लिए, आदि, और zipr, huskrप्रदर्शनीय उदाहरण के लिए, आदि, ताकि आप ट्रैक जिनमें से जो है रख सकते हैं। (और इसलिए कि यह सत्यापित करना आसान है कि हम उस चीज़ को नहीं लेते हैं जिसे हम एक धारणा के रूप में साबित करने की कोशिश कर रहे हैं! यह unhuskf . huskf = idसाबित होने पर उपयोग करने के लिए ठीक है unhuskr . huskr = id, लेकिन यह unhuskr . huskr = idउसी प्रमाण में मान लेना गलत होगा ।)

प्रत्येक कानून का प्रमाण मूल रूप से उसी तरह से आगे बढ़ता है: परिभाषाओं को अनियंत्रित करें Representable, आपको देने वाले समरूपता को छोड़ दें , फिर कार्यों के लिए अनुरूप कानून का उपयोग करें।

unhuskr . huskr
= { def. of unhuskr and huskr }
(unhuskf . index) . (tabulate . huskf)
= { index . tabulate = id }
unhuskf . huskf
= { unhuskf . huskf = id }
id

huskr . unhuskr
= { def. of huskr and unhuskr }
(tabulate . huskf) . (unhuskf . index)
= { huskf . unhuskf = id }
tabulate . index
= { tabulate . index = id }
id

zipr (unzipr fab)
= { def. of unzipr }
zipr (let (fa, fb) = unzipf (index fab) in (tabulate fa, tabulate fb))
= { def. of zipr }
let (fa, fb) = unzipf (index fab) in tabulate (zipf (index (tabulate fa), index (tabulate fb)))
= { index . tabulate = id }
let (fa, fb) = unzipf (index fab) in tabulate (zipf (fa, fb))
= { def. of (fa, fb) }
tabulate (zipf (unzipf (index fab)))
= { zipf . unzipf = id }
tabulate (index fab)
= { tabulate . index = id }
fab

unzipr (zipr (fa, fb))
= { def. of zipr }
unzipr (tabulate (zipf (index fa, index fb)))
= { def. of unzipr }
let (fa', fb') = unzipf (index (tabulate (zipf (index fa, index fb))))
in (tabulate fa', tabulate fb')
= { index . tabulate = id }
let (fa', fb') = unzipf (zipf (index fa, index fb))
in (tabulate fa', tabulate fb')
= { unzipf . zipf = id }
let (fa', fb') = (index fa, index fb)
in (tabulate fa', tabulate fb')
= { def. of fa' and fb' }
(tabulate (index fa), tabulate (index fb))
= { tabulate . index = id }
(fa, fb)

वर्तमान में विचार: instance StrongApplicative f => Representable f where type Rep f = forall x. f x -> xindexआसान है। मैंने tabulateअभी तक इस तरकीब के लिए काम नहीं किया है , लेकिन यह तांतलीकरण के करीब है।
डैनियल वैग्नर

@AsadSaeeduddin के साथ चर्चा में, मैं यह एक ही StrongApplicativeउदाहरण खोजने में कामयाब रहा , लेकिन कानूनों को साबित नहीं कर सका। यह पता लगाने के लिए बधाई! मैं Representableउदाहरण के रूप में अच्छी तरह से दिया करने की कोशिश की StrongApplicative, लेकिन एक अच्छा Repप्रकार के बारे में सोच नहीं सका - मैं यह जानने के लिए उत्सुक हूं कि यह कैसे forall x. f x -> xप्राप्त होता है ?
bradrn

@bradrn याद करते हैं कि परिकल्पना यह है कि इन चीजों में "छेद" का एक निश्चित सेट है जिसमें कौन से तत्व स्लॉट हैं। फिर प्रकार के कार्य forall x. f x -> xवास्तव में वे कार्य हैं जो एक छेद चुनते हैं और उस छेद में मूल्य वापस करते हैं। (और, कैसे लागू करने के बारे में सोचते हुए tabulate, मैं टाइप के लिए एक आपत्ति के साथ आया हूं unhusk; विवरण के लिए स्वयं प्रश्न पर टिप्पणी देखें।)
डैनियल वैगनर

धन्यवाद @DanielWagner! यह वास्तव में चतुर दृष्टिकोण है - मैंने ऐसा नहीं सोचा होगा।
2:10 बजे

इसे लागू करने की कोशिश के बाद, मुझे नहीं लगता कि मैं आश्वस्त हूं कि forall x. f x -> xयह काम करेगा Rep। मेरा तर्क यह है कि, इसका उपयोग करके Rep, आप किसी भी प्रकार के indexलिए लिख सकते हैं , न कि केवल - इसलिए मुझे संदेह है कि यह बहुत सामान्य हो सकता है। StrongApplicativeforall x. f x -> x
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.