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

如何将all/any应用于返回Either类型的函数?

实现Either上下文中的all/any函数

问题背景

我们有一个返回Either String Bool的函数,用于判断两个有理数的关系,遇到除数为0时返回错误信息:

testPre :: Rational -> Rational -> Either String Bool
testPre a b
  | b == 0 = Left "Shouldn't be 0" 
  | a > b = Right True
  | a <= b = Right False

需要实现适配Either String Bool类型的all和any函数,使其能在Either上下文处理列表,满足以下预期行为:

-- all函数预期结果
allEither (testPre 3) [1,2]  =>  Right True
allEither (testPre 3) [1,2,3]  =>  Right False

-- any函数预期结果
anyEither (testPre 3) [1,5]  =>  Right True
anyEither (testPre 3) [5,6]  =>  Right False

-- 遇到错误时立即返回
anyEither (testPre 3) [1,0,3]  =>  Left "Shouldn't be 0" 

实现方案

核心逻辑是遍历列表时优先处理错误:一旦遇到Left就终止遍历并返回该错误;若为Right Bool则按照all/any的语义累积结果。

代码实现

import Data.Ratio (Rational)

testPre :: Rational -> Rational -> Either String Bool
testPre a b
  | b == 0 = Left "Shouldn't be 0" 
  | a > b = Right True
  | a <= b = Right False

-- 适配Either的all函数:所有元素满足条件则返回Right True,否则Right False,遇错返回Left
allEither :: (a -> Either e Bool) -> [a] -> Either e Bool
allEither _ [] = Right True
allEither f (x:xs) = do
  current <- f x
  if current then allEither f xs else Right False

-- 适配Either的any函数:任一元素满足条件则返回Right True,否则Right False,遇错返回Left
anyEither :: (a -> Either e Bool) -> [a] -> Either e Bool
anyEither _ [] = Right False
anyEither f (x:xs) = do
  current <- f x
  if current then Right True else anyEither f xs

验证结果

调用示例与预期完全一致:

allEither (testPre 3) [1,2]  -- 输出 Right True
allEither (testPre 3) [1,2,3]  -- 输出 Right False

anyEither (testPre 3) [1,5]  -- 输出 Right True
anyEither (testPre 3) [5,6]  -- 输出 Right False

anyEither (testPre 3) [1,0,3]  -- 输出 Left "Shouldn't be 0"

细节说明

  • 利用Haskell的do语法糖简化Either的链式处理:当f x返回Left时,整个do块会直接短路返回该错误,无需额外判断。
  • 空列表的返回值遵循标准all/any的语义:all对空列表返回True,any对空列表返回False,这里对应包装为Right值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:08:09