You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell用Do-notation重写列表推导式的else分支写法问题

问题原因

你当前的报错核心是if两个分支返回值类型不统一:

  • then分支返回return (a,a',b),类型是[(Int,Int,Int)](列表Monad中return x等价于[x],即单个元素的列表)
  • else分支返回return (),类型是[()],和函数声明的预期返回类型完全不匹配,因此类型检查失败。

解决方案

列表Monad中,要表示「当前分支不产出任何结果」,不需要返回包装后的空值,直接返回**空列表[]**即可,修正后的代码如下:

findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = do
  a  <- as
  a' <- as 
  b  <- bs
  if a + a' == b then return (a, a', b) 
                 else []

此时两个分支的类型统一为[(Int,Int,Int)],即可正常通过类型检查。

更符合Monad风格的优化写法

你也可以使用Control.Monad模块中的guard函数替代手写if判断,和你最初列表推导式的条件筛选逻辑完全等价:

import Control.Monad (guard)

findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = do
  a  <- as
  a' <- as 
  b  <- bs
  guard (a + a' == b)
  return (a,a',b)

guard在条件不满足时会直接返回空列表终止当前分支逻辑,条件满足时返回无副作用的[()],写法更简洁直观。

内容的提问来源于stack exchange,提问作者daikonradish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 07:45:08