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

Haskell中如何将多函数整合为一个双向查找函数?

解决Haskell双向查找函数的整合问题

你的代码核心问题

  1. lookupLhs/lookupRhs缺少空列表处理:当遍历到列表末尾未找到匹配项时,会触发非穷尽模式错误,必须补上空列表的base case。
  2. bidirectionalLookup的参数传递与结果包装错误:你只给lookupLhs/lookupRhs传了第一个参数,漏掉了列表参数;同时返回的Maybe b/Maybe a没有按照要求包装成Maybe (Either a b)类型。

修正后的完整代码

namesAges = [("Felix", 45), ("Grace", 25), ("Hans", 57), ("Ivy", 25)]

lookupLhs :: Eq a => a -> [(a, b)] -> Maybe b
lookupLhs _ [] = Nothing  -- 空列表直接返回Nothing
lookupLhs x  ((l, r) : rest) = if x == l then Just r else lookupLhs x rest

lookupRhs :: Eq b => b -> [(a, b)] -> Maybe a
lookupRhs _ [] = Nothing  -- 同样处理空列表
lookupRhs x ((l, r) : rest) = if x == r then Just l else lookupRhs x rest

bidirectionalLookup :: (Eq a, Eq b) => Either a b -> [(a, b)] -> Maybe (Either a b)
bidirectionalLookup (Left x) list = fmap Right (lookupLhs x list)
bidirectionalLookup (Right x) list = fmap Left (lookupRhs x list)

关于函数形式的选择

模式匹配是这里最适合的写法。Haskell处理Either这类代数数据类型时,模式匹配是最直观、符合语言习惯的方式——你已经在bidirectionalLookup里用模式匹配拆分Either的两个分支了,这完全正确,不需要换成if表达式或case表达式(case本质也是模式匹配的另一种写法,这里直接匹配参数更简洁)。

测试验证

运行以下代码可以验证结果符合预期:

main = do
  print $ bidirectionalLookup (Left "Grace") namesAges == Just (Right 25)  -- 输出True
  print $ bidirectionalLookup (Right 57) namesAges == Just (Left "Hans")    -- 输出True
  print $ bidirectionalLookup (Left "Zoe") namesAges == Nothing             -- 输出True
  print $ bidirectionalLookup (Right 99) namesAges == Nothing               -- 输出True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:50:25