2017-12-29 89 views
7

मैं बहुत मासूम दिखने कोडTypeFamilies या GADTs अचानक मान्य कोड

data Config = Config 
    { cInts :: [Int] 
    , cStrings :: [String] } 

instance Semigroup Config where 
    c1 <> c2 = Config 
     { cInts = andCombiner cInts 
     , cStrings = andCombiner cStrings } 
     where 
     andCombiner field = field c1 <> field c2 

यह कम्पाइल और ठीक काम करता है टूट जाता है। लेकिन अगर मैं TypeFamilies जोड़ सकते हैं या GADTs विस्तार मैं बहुत अजीब त्रुटि देखें:

.../Main.hs:19:22: error: 
    • Couldn't match type ‘Int’ with ‘[Char]’ 
     Expected type: [String] 
     Actual type: [Int] 
    • In the ‘cStrings’ field of a record 
     In the expression: 
     Config {cInts = andCombiner cInts, cStrings = andCombiner cStrings} 
     In an equation for ‘<>’: 
      c1 <> c2 
      = Config 
       {cInts = andCombiner cInts, cStrings = andCombiner cStrings} 
      where 
       andCombiner field = field c1 <> field c2 
    | 
19 |   , cStrings = andCombiner cStrings } 
    |      ^^^^^^^^^^^^^^^^^^^^ 

.../Main.hs:19:34: error: 
    • Couldn't match type ‘[Char]’ with ‘Int’ 
     Expected type: Config -> [Int] 
     Actual type: Config -> [String] 
    • In the first argument of ‘andCombiner’, namely ‘cStrings’ 
     In the ‘cStrings’ field of a record 
     In the expression: 
     Config {cInts = andCombiner cInts, cStrings = andCombiner cStrings} 
    | 
19 |   , cStrings = andCombiner cStrings } 
    |         ^^^^^^^^ 

क्या इस संकलक त्रुटि के लिए कारण हो सकता है?

उत्तर

10

यह -XMonoLocalBinds-XGADTs और -XTypeFamilies के कारण है। GHC डॉक्स मैं लिंक करने के बाद से शब्दावली का प्रयोग

instance Semigroup Config where 
    c1 <> c2 = Config 
     { cInts = andCombiner cInts 
     , cStrings = andCombiner cStrings } 
     where 
     andCombiner :: Semigroup a => (Config -> a) -> a 
     andCombiner field = field c1 <> field c2 

: आप andCombiner करने के लिए एक प्रकार हस्ताक्षर जोड़कर फिर से संकलित करने के लिए अपने कोड प्राप्त कर सकते हैं (या -XNoMonoLocalBinds को चालू करके, हालांकि मुझे ऐसा नहीं अनुशंसा करते हैं कि) , andCombiner पूरी तरह से सामान्यीकृत नहीं है क्योंकि यह c1 और c2 का उल्लेख करता है जो बंद या आयात नहीं होते हैं।

+4

क्या आपका मतलब है '-XMooLocalBinds' * बंद *,' -XNoMonoLocalBinds' के साथ? – HTNW

+0

@ एचटीएनडब्ल्यू हाँ, बहुत बहुत धन्यवाद! – Alec

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