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

Haskell多态函数实现:基于Either的EvalResult二元运算

实现EvalResult的多态二元运算函数

嘿,作为Haskell新手能想到抽象这种运算逻辑真的超棒!咱们一步步把这个evalResultOp函数给搞定。

首先先明确你已经定义的类型(方便咱们统一语境):

type Variable = String
type Value = Float
type EvalError = [Variable]
type EvalResult a = Either EvalError a

你的需求很清晰:接收一个二元运算函数,以及两个EvalResult参数,只有当两者都成功(也就是Right包裹的值)时才执行运算;只要有一个是错误(Left包裹的EvalError),就返回对应的错误。

正确的函数类型与实现

首先修正函数的类型签名,最终的类型应该是:

evalResultOp :: (a -> b -> c) -> EvalResult a -> EvalResult b -> EvalResult c

这个签名表示:传入一个从a和b到c的二元函数,两个分别包裹a和b的EvalResult,返回一个包裹c的EvalResult。

接下来用模式匹配实现逻辑,这是Haskell处理这类分支最直观的方式:

evalResultOp f (Right x) (Right y) = Right (f x y)
evalResultOp _ (Left err) _        = Left err
evalResultOp _ _ (Left err)        = Left err

代码解释

  • 第一行:当两个输入都是Right时,取出里面的x和y,用传入的函数f计算结果,再用Right包裹起来返回。
  • 第二行:如果第一个输入是Left(错误),不管第二个输入是什么,直接返回这个错误。
  • 第三行:如果第一个输入没问题,但第二个是Left,就返回第二个的错误。

测试例子

咱们用加法来测试这个函数:

-- 基于evalResultOp实现加法运算
addEval :: EvalResult Value -> EvalResult Value -> EvalResult Value
addEval = evalResultOp (+)

-- 测试成功场景
test1 :: EvalResult Value
test1 = addEval (Right 3.5) (Right 2.1)  -- 结果是 Right 5.6

-- 测试第一个参数错误的场景
test2 :: EvalResult Value
test2 = addEval (Left ["x"]) (Right 4.0)  -- 结果是 Left ["x"]

-- 测试第二个参数错误的场景
test3 :: EvalResult Value
test3 = addEval (Right 1.0) (Left ["y", "z"])  -- 结果是 Left ["y", "z"]

扩展小技巧

如果你的需求后续需要合并两个错误(比如当两个输入都是错误时,把错误列表合并),可以修改模式匹配的顺序,专门处理双错误的情况:

evalResultOp f (Right x) (Right y) = Right (f x y)
evalResultOp _ (Left err1) (Left err2) = Left (err1 ++ err2)
evalResultOp _ (Left err) _        = Left err
evalResultOp _ _ (Left err)        = Left err

这样当两个输入都是错误时,会返回合并后的错误列表,比如evalResultOp (+) (Left ["x"]) (Left ["y"])会得到Left ["x","y"]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:16:59