2015-01-08 4 views
6

के साथ जिपर में कदम उठाने के साथ मैं lens और zippers के साथ संघर्ष कर रहा हूं। नीचे दिए गए कोड पर विचार करें ghci'to` lens

> import Control.Lens 
> import Control.Zipper 
> 
> :t within (ix 1) $ zipper ([1,2,3] :: [Int]) 
> within (ix 1) $ zipper ([1,2,3] :: [Int]) 
    :: Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> Int) 

data A t = A t होने में चलाने के लिए, मैं कैसे की तरह ज़िपर के प्रकार बना सकते हैं: Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> A Int)?

मैं within (ix 1 . to A) $ zipper ([1,2,3] :: [Int]) कोशिश की, लेकिन यह एक त्रुटि देता है:

Could not deduce (Contravariant 
        (Bazaar (Indexed Int) (A Int) (A Int))) 
    arising from a use of ‘to’ 
from the context (Control.Monad.MonadPlus m) 
    bound by the inferred type of 
      it :: Control.Monad.MonadPlus m => 
       m (Zipper Top Int [Int] :>> A Int) 
    at Top level 
In the second argument of ‘(.)’, namely ‘to A’ 
In the first argument of ‘within’, namely ‘(ix 1 . to A)’ 
In the expression: within (ix 1 . to A) 

उत्तर

2

एक तरह से एक Iso बनाने के लिए और उस के साथ रचना के लिए है।

> import Control.Lens 
> import Control.Zipper 
> 
> data A t = A t 
> let _A = iso A (\(A a) -> a) 
> 
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int]) 
> :t a 
a :: MonadPlus m => m (Zipper Top Int [Int] :>> A Int) 
> a ^? _Just . focus 
Just (A 2) 

संपादित करें:: GHCi में कारण आप की जरूरत (\(A a) -> a) ताकि आप वापस बाहर निकल सकते है।

> data A t = A t 
> let _A = iso A (error "Can't unA") 
> 
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int]) 
> a ^? _Just . focus 
Just (A 2) 
> fmap upward a ^? _Just . focus 
Just [1,*** Exception: Can't unA 

मैं वहाँ A निकालने के लिए एक समारोह के बिना इस बनाने के लिए एक वैध तरीका है नहीं लगता। आपने एक अवैध Traversal लिख सकता है लेकिन यह अभी भी ठीक से काम नहीं करेगा:

> data A t = A t 
> let _A f a = a <$ f (A a) 
> 
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int]) 
> let b = a & _Just . focus .~ A 10 
> b ^? _Just . focus 
Just (A 10) 
> fmap upward b ^? _Just . focus 
Just [1,2,3] -- Should be Just [1, 10, 3] 
+0

वहाँ specyfing बिना यह करने के लिए कोई तरीका है '(\ (ए क) -> एक)' समारोह? क्या मैं अभी यहां 'अपरिभाषित' पास कर सकता हूं यदि मेरे मामले में यह स्पष्ट नहीं है? – remdezx

+0

वास्तव में नहीं। समस्या यह है कि आप बैक अप नहीं कर पाएंगे। वापस पाने के लिए 'ऊपर की ओर' का उपयोग करना 'अपरिभाषित' होगा। – cchalmers

+1

मुझे लगता है ... क्या 'आईएसओ' से कोई अन्य विकल्प हैं? – remdezx

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