Haskell中如何将多函数整合为一个双向查找函数?
解决Haskell双向查找函数的整合问题
你的代码核心问题
lookupLhs/lookupRhs缺少空列表处理:当遍历到列表末尾未找到匹配项时,会触发非穷尽模式错误,必须补上空列表的base case。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
相关产品推荐
相关产品推荐

