2013-07-08 10 views
7

की आवश्यकता है निम्नलिखित कोड संकलन नहीं करता है:अनुक्रमण सूची monoid बाधा

{-# LANGUAGE TemplateHaskell #-} 

import Control.Lens 

data MyType = MyType Int 
data Outer = Outer { _inners :: [ Inner ] } 
data Inner = Inner { _val :: MyType } 

$(makeLenses ''Outer) 
$(makeLenses ''Inner) 

i1 = Inner (MyType 1) 
i2 = Inner (MyType 2) 

o = Outer [i1, i2] 

x = o ^. inners . ix 0 . val 

इस त्रुटि

Toy.hs:17:23: 
No instance for (Data.Monoid.Monoid MyType) 
    arising from a use of `ix' 
Possible fix: 
    add an instance declaration for (Data.Monoid.Monoid MyType) 
In the first argument of `(.)', namely `ix 0' 
In the second argument of `(.)', namely `ix 0 . val' 
In the second argument of `(^.)', namely `inners . ix 0 . val' 

यह सोचते हैं कि यह मतलब नहीं है MyType एक होने के लिए दे रही है मोनॉयड, मैं लेंस कैसे प्राप्त कर सकता हूं (या ट्रैवर्सल, या जो भी सबसे उपयुक्त है - मुझे भेदों के बारे में निश्चित नहीं है) जो मुझे इस नेस्टेड फ़ील्ड तक पहुंचने की अनुमति देता है? अधिमानतः दोनों को पढ़ने और अपडेट करने की क्षमता के साथ।

+1

[यह सवाल] (http://stackoverflow.com/q/13434568/712548) (और मेरा उत्तर) यहां भी प्रासंगिक हो सकता है। – shachaf

उत्तर

9

क्योंकि ix n विफल हो सकता है (उदा: n >= length list) आपको असफल होने का एक साफ तरीका चाहिए। पसंद की साफ विफलता तत्व Monoid से है। तो सवाल उठता है कि अगर आपका प्रकार एक मोनॉयड नहीं हो सकता है तो आप इस कोड को कैसे विफल कर सकते हैं?

मैं तुम्हें ^. के बजाय ^? उपयोग करते हैं, जिससे पुन: उपयोग का सुझाव Monoid नामित Maybe:

*Main> o ^? inners . ix 2 . val 
Nothing 
*Main> o ^? inners . ix 0 . val 
Just (MyType 1) 
+2

एक छोटे से नोट के रूप में, यहां 'मोनॉयड' उदाहरण का उपयोग किया जा रहा है 'पहला ए', 'शायद ए' नहीं है (क्योंकि हमारे पास एफ़िन ट्रैवर्सल के बारे में बात करने के लिए पर्याप्त प्रकार की श्रेणी पदानुक्रम नहीं है)। – shachaf

+0

आह, धन्यवाद shachaf –

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