vro*_*911 8 haskell type-inference type-families gadt
我有非常无辜的代码
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
Run Code Online (Sandbox Code Playgroud)
它编译并正常工作.但是,如果我添加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 }
| ^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
这个编译器错误的原因是什么?
Ale*_*lec 11
这是由于-XMonoLocalBinds它-XGADTs和-XTypeFamilies暗示.您可以通过添加类型签名来再次编译代码andCombiner(或通过启用-XNoMonoLocalBinds,但我不建议这样做):
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
Run Code Online (Sandbox Code Playgroud)
使用我所链接的GHC文档中的术语,andCombiner并未完全概括,因为它提及c1并且c2未关闭或导入.