Yesod中Handler分支返回类型不匹配的编译错误咨询
问题分析与解决方案
核心问题:分支类型不匹配
你的编译器报错和分支顺序无关,本质是两个case分支的返回类型不一致——Haskell作为强类型语言,要求case表达式的所有分支必须返回相同类型:
- 处理
Apple code时,你返回的是[String](单元素字符串列表) - 处理
Apples codes时,map (\x -> ["APPLE"++ show x]) codes的返回值是[[String]](字符串列表的列表),因为每个x被映射成一个单元素列表,再组合成大列表
类型推断的行为
Haskell的类型推断会优先根据第一个分支的类型,要求后续分支必须匹配该类型:
- 当
Apple分支在前时,编译器推断整个case表达式的类型应该是[String],但Apples分支返回[[String]],所以报错“期望[String]而非[[String]]” - 当
Apples分支在前时,编译器推断类型应该是[[String]],但Apple分支返回[String],所以报错“期望[[String]]而非[String]”
这和Yesod无关,是Haskell本身的类型系统规则。
正确修改方案
根据你的需求:单个Apple返回一个字符串(包装成列表),多个Apples返回字符串列表,需要让两个分支都返回[String]类型。修改Apples分支的map逻辑,直接生成字符串而非字符串列表:
case (apple runReq) of Apple code -> ["APPLE" ++ show code] Apples codes -> map (\x -> "APPLE" ++ show x) codes
这样:
Apple分支返回[String](包含一个元素的列表)Apples分支返回[String](包含多个元素的列表)
类型完全匹配,编译器不再报错。
内容的提问来源于stack exchange,提问作者Shawn Zhang
相关产品推荐
相关产品推荐

