2015-12-22 8 views
5
से अधिक

मैं Control.Lens के बारे में साइमन Peyton जोन्स 'बात देखा, और वह पता चला है कि लेंस और LensR यहाँ के रूप में परिभाषित isomorphic हैं Traversal समाकृतिकता ट्रैवर्सल के साथ ऐसा ही करें:Control.Lens:</p> <pre><code>type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t data LensR s t a b = LensR { viewR :: s -> a, setR :: b -> s -> t } </code></pre> मैं कोशिश कर रहा हूँ <p>: toListOf करने और

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t 

data TraversalR s t a b = TraversalR { 
    toListOfR :: s -> [a], 
    overR :: (a -> b) -> s -> t 
} 

newtype CL a b = CL { getCL :: [a] } -- ConstantList 

instance Functor (CL a) where 
    fmap _ (CL xs) = CL xs 

instance Applicative (CL a) where 
    pure _ = CL [] 
    (CL xs) <*> (CL ys) = CL (xs ++ ys) 


travToTravR :: Traversal s t a b -> TraversalR s t a b 
travToTravR tr = TraversalR { 
    toListOfR = getCL . tr (CL . pure), 
    overR = \f -> runIdentity . tr (Identity . f) 
} 

लेकिन मैं travRToTrav के साथ अटक गया हूं। यह सबसे अच्छा मैं के साथ आ सकता है:

travRToTrav :: TraversalR s t a b -> Traversal s t a b 
travRToTrav trR a2fb s = (\bs-> overR trR magic s) <$> f_bs 
    where as = toListOfR trR s 
     f_bs = sequenceA . map a2fb $ as 
     magic = undefined 

यहाँ, जादू :: एक -> ख है, लेकिन मैं एक सामान्य समारोह नहीं कर सकते हैं (एक -> ख)। इसके बजाय, मैं आंशिक कार्य करके धोखा दे सकता हूं: मुझे पता है कि फ़ंक्शन को किसी भी प्रकार के मूल्य के लिए वापस लौटना चाहिए जो ट्रैवर्सबल में है। तो मैं एएस और बीएस से एक एसोसिएशन सूची बना सकता हूं, और उसके बाद से आंशिक कार्य कर सकता हूं।

क्या यह काम करता है? यदि हां, तो कृपया मुझे बताएं कि एक बेहतर तरीका है!

या मैंने ट्रैवर्सबलआर के लिए गलत फॉर्म चुना है, और वास्तव में कोई आइसोमोर्फिज्म नहीं है?

किसी भी सलाह के लिए धन्यवाद।


संपादित करें:

तो एंड्रास कोवाक्स के लिए धन्यवाद मैं अब लगता है कि TraversalR इस तरह दिखना चाहिए: फिर travRToTrav बहुत lensRToLens के समान है

data TraversalR s t a b = TraversalR { 
    toListOfR :: s -> [a], 
    setListR :: [b] -> s -> t 
} 

:

travRToTrav :: TraversalR s t a b -> Traversal s t a b 
travRToTrav trR a2fb s = (`setL` s) <$> f_bs 
    where as = toListOfR trR s 
     f_bs = sequenceA . map a2fb $ as 
     setL = setListR trR 

लेकिन फिर, travToTravR में setListR को परिभाषित करने के लिए कैसे? असल में, अनुक्रमित ट्रैवर्सल कैसे काम करते हैं?

+0

'ट्रैवर्सलआर' अच्छा प्रतीत नहीं होता है। 'ट्रैवर्सल' के साथ, आप राज्यव्यापी ट्रैवर्सल और ई कर सकते हैं। जी। प्रत्येक 'ए' को अपनी स्थिति के सूचकांक के साथ प्रतिस्थापित करें। '(ए -> बी) -> एस -> टी' के साथ, यह संभव नहीं है। –

+0

ओह ठीक - मुझे एहसास नहीं हुआ था। ट्रैवर्सलर को तब कैसा दिखना चाहिए, क्या आपको लगता है? – RhubarbAndC

+1

'ओवरआर :: [बी] -> एस -> टी' 'ट्रैवर्सलआर' को [' biplate'] के समान ही बना देगा (https://hackage.haskell.org/package/uniplate-1.6.12/docs/Data -जेनरिक्स-यूनीप्लेट-ऑपरेशंस.html # टी: बायप्लेट), ताकि एक कोशिश के लायक हो। –

उत्तर

2

एंड्रस कोवाक्स के साथ चर्चा के बाद, मुझे एक अच्छा सरल जवाब मिला है: हमें राज्य मोनड की आवश्यकता है, जो एक आवेदक मजेदार है। यहां संपूर्ण आइसोमोर्फिज्म है:

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> (s -> f t) 

data TraversalR s t a b = TraversalR { 
    toListOfR :: s -> [a], 
    setListR :: [b] -> s -> t 
} 

newtype CL a b = CL { getCL :: [a] } -- ConstantList 

instance Functor (CL a) where 
    fmap _ (CL xs) = CL xs 

instance Applicative (CL a) where 
    pure _ = CL [] 
    (CL xs) <*> (CL ys) = CL (xs ++ ys) 

collectBs :: State [b] b 
collectBs = state $ \xs -> case xs of []  -> error "Too few bs" 
             (y:ys) -> (y,ys) 

travToTravR :: Traversal s t a b -> TraversalR s t a b 
travToTravR tr = TraversalR { 
    toListOfR = getCL . tr (CL . pure), 
    setListR = \bs s -> evalState (tr (const collectBs) s) bs 
} 

travRToTrav :: TraversalR s t a b -> Traversal s t a b 
travRToTrav trR a2fb s = (`setL` s) <$> f_bs 
    where as = toListOfR trR s 
     f_bs = sequenceA . map a2fb $ as 
     setL = setListR trR 
संबंधित मुद्दे

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