Haskell Wreq编译报错:无法匹配预期类型GHC.Exts.Item a0
问题成因
这个错误是OverloadedLists GHC扩展和wreq库post函数的多态参数设计共同导致的:
- 当你开启了
OverloadedLists扩展时,代码里的字面量列表["num" := (31337 :: Int)]不再是固定的[a]列表类型,而是多态的、任意实现了GHC.Exts.IsList类型类的类型,GHC.Exts.Item a是IsList类型类定义的关联类型,用来指代类型a对应的元素类型。 wreq的post函数第二个参数是Postable类型类约束的多态类型,它支持传入多种可作为POST请求体的类型(比如字节串、表单参数列表、JSON值等),编译器无法从上下文推导出你传入的多态列表需要匹配哪一种Postable实例,也就无法确定列表的实际类型,因此出现了类型变量a0模糊的报错,编译器不知道GHC.Exts.Item a0应该匹配你提供的FormParam类型。
另外还有一个隐性的可能诱因:(:=)操作符的第一个参数要求是ByteString类型,如果你没有开启OverloadedStrings扩展,字面量"num"是默认的String类型,也会进一步干扰类型推导,加重类型模糊的问题。
解决方案
你可以任选以下一种方式修复:
- 给列表添加显式类型标注,明确告知编译器你要传入的是
FormParam列表:
runPost :: IO String runPost = do res <- post "http://httpbin.org/post" (["num" := (31337 :: Int)] :: [FormParam]) return $ show res
- 如果你不需要用到
OverloadedLists扩展,直接在代码头部关掉该扩展即可。 - 如果你还没有开
OverloadedStrings扩展,也请开启该扩展,保证"num"可以自动推导为ByteString类型。
内容的提问来源于stack exchange,提问作者Emanegux
相关产品推荐
相关产品推荐

