2017-12-29 119 views
7

Tôi có rất ngây thơ nhìn đangTypeFamilies hoặc GADTs đột nhiên phá vỡ mã hợp lệ

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 

Nó biên dịch và hoạt động tốt. Tuy nhiên nếu tôi thêm TypeFamilies hoặc GADTs mở rộng tôi thấy lỗi rất lạ:

.../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 } 
    |         ^^^^^^^^ 

gì có thể là lý do cho lỗi biên dịch này?

Trả lời

10

Điều này là do -XMonoLocalBinds-XGADTs-XTypeFamilies ngụ ý. Bạn có thể lấy mã của bạn để biên dịch một lần nữa bằng cách thêm một chữ ký kiểu để andCombiner (hoặc bằng cách bật -XNoMonoLocalBinds, mặc dù tôi làm không khuyên):

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 

Sử dụng các thuật ngữ từ các tài liệu GHC tôi đã liên kết , andCombiner không được tổng quát hoàn toàn vì đề cập đến c1c2 không được đóng hoặc được nhập.

+4

Bạn có nghĩa là tắt '-XMonoLocalBinds' * off *, với' -XNoMonoLocalBinds' không? – HTNW

+0

@HTNW Vâng, cảm ơn bạn rất nhiều! – Alec

Các vấn đề liên quan