2017-12-29 40 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입니다. (나는 을 할 수 있지만하지는 것이 좋습니다, 또는 -XNoMonoLocalBinds 설정하여) 당신은 andCombiner에 유형 서명을 추가하여 다시 컴파일 코드를 얻을 수 있습니다 :

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 

내가 링크 한 GHC의 문서에서 용어를 사용 , andCombiner은 닫히거나 가져 오기되지 않은 c1c2을 언급하기 때문에 완전히 일반화되지 않았습니다.

+4

'-XNoMonoLocalBinds' *를 끄고'-XNoMonoLocalBinds'를 사용 하시겠습니까? – HTNW

+0

@HTNW 네, 고맙습니다! – Alec