如何编写Haskell函数生成两个列表的笛卡尔积
问题修正说明
你的代码存在两类核心错误:
- 基础分支逻辑与类型不匹配:前两个模式中,当任意一个输入列表为空时直接返回另一个列表,返回值类型和签名声明的
[c]不匹配——实际上只要有一个输入列表为空,笛卡尔积结果就是空列表,不可能返回原输入的[a]或[b]类型值。同时这两个分支存在匹配重叠问题,传入两个空列表时会触发模式匹配冲突。 - 最终分支语法完全非法:等式左侧没有做参数绑定,右侧直接堆砌了未定义的
unionHelper、func1标识符,参数顺序混乱,不符合Haskell函数定义规则。
正确实现
最简洁的实现可以直接用Haskell列表推导,完全贴合笛卡尔积的遍历逻辑:
cartesianProduct :: (a -> b -> c) -> [a] -> [b] -> [c] cartesianProduct f xs ys = [f x y | x <- xs, y <- ys]
如果需要显式递归版本,参考如下实现:
cartesianProduct :: (a -> b -> c) -> [a] -> [b] -> [c] cartesianProduct _ [] _ = [] cartesianProduct _ _ [] = [] cartesianProduct f (x:xs) ys = map (f x) ys ++ cartesianProduct f xs ys
递归逻辑为:取出第一个列表的头部元素,和第二个列表的所有元素应用组合函数生成一段结果,再拼接第一个列表剩余元素和第二个列表的笛卡尔积结果即可。
测试示例
在GHCi中运行可以验证效果:
ghci> cartesianProduct (,) ["a","b"] [1,2] [("a",1),("a",2),("b",1),("b",2)] ghci> cartesianProduct (+) [10,20] [1,2,3] [11,12,13,21,22,23]
内容的提问来源于stack exchange,提问作者nikojokic15
相关产品推荐
相关产品推荐

