2015-07-31 7 views
14

मेरे पास में उपयोग किए जाने वाले प्रकार की प्रकृति के बारे में सैद्धांतिक प्रश्न है जो कोयोनोना लेम्मा को समझाते हुए कई उदाहरण हैं। उन्हें आम तौर पर को "प्राकृतिक परिवर्तन" के रूप में संदर्भित किया जाता है जो कि मेरे ज्ञान के लिए मज़दूरों के बीच मैपिंग के लिए होता है। मुझे कौन सा पहेली है कि इन उदाहरणों में वे कभी-कभी Set से कुछ मज़ेदार F पर मानचित्र करते हैं। तो यह वास्तव में functors के बीच एक मैपिंग होने के लिए semm नहीं है, लेकिन कुछ और अधिक आराम से।क्या "प्राकृतिक परिवर्तन" हम वास्तव में "प्राकृतिक परिवर्तन" प्राप्त करने के लिए कोयोनिया पर लागू होते हैं?

{-# LANGUAGE GADTs #-} 
{-# LANGUAGE RankNTypes #-} 
module Coyo where 

import   Data.Set (Set) 
import qualified Data.Set as Set 

data Coyoneda f a where 
    Coyoneda :: (b -> a) -> f b -> Coyoneda f a 

instance Functor (Coyoneda f) where 
    fmap f (Coyoneda c fa) = Coyoneda (f . c) fa 

set :: Set Int 
set = Set.fromList [1,2,3,4] 

lift :: f a -> Coyoneda f a 
lift fa = Coyoneda id fa 

lower :: Functor f => Coyoneda f a -> f a 
lower (Coyoneda f fa) = fmap f fa 

type NatT f g = forall a. f a -> g a 

coyoset :: Coyoneda Set Int 
coyoset = fmap (+1) (lift set) 

applyNatT :: NatT f g -> Coyoneda f a -> Coyoneda g a 
applyNatT n (Coyoneda f fa) = Coyoneda f (n fa) 

-- Set.toList is used as a "natural transformation" here 
-- while it conforms to the type signature of NatT, it 
-- is not a mapping between functors `f` and `g` since 
-- `Set` is not a functor. 
run :: [Int] 
run = lower (applyNatT Set.toList coyoset) 

मैं यहाँ क्या गलत समझ रहा हूँ:

यहाँ प्रश्न में कोड है?

संपादित करें: फ्रीनोड में # हास्केल पर चर्चा के बाद मुझे लगता है कि मुझे अपने प्रश्न को थोड़ा स्पष्ट करने की आवश्यकता है। यह मूल रूप से है: "Set.toList श्रेणी सैद्धांतिक अर्थ में क्या है? चूंकि यह स्पष्ट रूप से (?) प्राकृतिक परिवर्तन नहीं है"।

उत्तर

13

n लिए हास्केल में एक प्राकृतिक transfomation यह (सभी f के लिए) का पालन करने की जरूरत है

(fmap f) . n == n . (fmap f) 

यह Set.toList के लिए मामला नहीं है किया जाना है।

fmap (const 0) . Set.toList  $ Set.fromList [1, 2, 3] = [0, 0, 0] 
Set.toList  . Set.map (const 0) $ Set.fromList [1, 2, 3] = [0] 

इसके बजाय यह कानूनों के एक अलग सेट का पालन करता है।

: वहाँ एक और परिवर्तन n' वापस दूसरे रास्ते ऐसी है कि निम्नलिखित रखती

n' . (fmap f) . n == fmap f 

हम f = id चुनें और functor कानून fmap id == id लागू हम देख सकते हैं यह संकेत मिलता है कि n' . n == id और इसलिए हम एक ऐसी ही सूत्र है कि यदि है

(fmap f) . n' . n == n' . (fmap f) . n == n' . n . (fmap f) 

n = Set.toList और n' = Set.fromList इस कानून का पालन करें।

Set.map (const 0) . Set.fromList . Set.toList  $ Set.fromList [1, 2, 3] = fromList [0] 
Set.fromList  . fmap (const 0) . Set.toList  $ Set.fromList [1, 2, 3] = fromList [0] 
Set.fromList  . Set.toList  . Set.map (const 0) $ Set.fromList [1, 2, 3] = fromList [0] 

मैं नहीं जानता कि क्या हम को देख कि Set सूचियों में से एक तुल्यता वर्ग है की तुलना में यह अन्य फोन कर सकते हैं। Set.toList समकक्ष वर्ग का प्रतिनिधि सदस्य और Set.fromList उद्धरण है।

शायद यह ध्यान देने योग्य है कि Set.fromList एक प्राकृतिक परिवर्तन है। कम से कम यह हैस्क की उचित उपश्रेणी पर है जहां a == b का अर्थ है f a == f b (यहां ==Eq से समानता है)। यह हास्क की उपश्रेणी है जहां Set एक मजेदार है; इसमें degenerate things like this शामिल नहीं है।

leftaroundabout यह भी कहा कि Set.toListHask की उपश्रेणी जहां morphisms injective functions where f a == f b implies a == b तक ही सीमित हैं पर एक प्राकृतिक परिवर्तन है।

+3

इंजेक्शन उपश्रेणी पर, यहां तक ​​कि 'toList' भी एक प्राकृतिक परिवर्तन है। – leftaroundabout

+0

उत्तर के लिए धन्यवाद! तो 'n'' और' n' यहां एक सेक्शन/रीट्रैक्शन जोड़ी बनाते हैं? – raichoo

+1

@raichoo हां, 'n' और' n ''n' के बाद सेक्शन/रीट्रैक्शन जोड़े का पूरा परिवार हैं। एन == आईडी'। सभी अनुभाग/पीछे हटने वाले जोड़े मजबूत कानून 'एन' का पालन नहीं करेंगे। एफएमएपी एफ एन == एफएमएपी एफ'। – Cirdec

संबंधित मुद्दे