Haskell 实现整数列表拆分为奇偶两个子列表的问题求助
你代码的问题
- 类型签名错误:你当前的
split :: [a] -> ([a], [a])声明可以接收任意类型的列表,但后续用到的mod运算仅支持数值类型,需要添加类型类约束,修改为Integral a => [a] -> ([a], [a])才能通过类型检查。 - 运算符调用语法错误:Haskell中函数名默认是前缀调用,要作为中缀运算符使用需要用反引号包裹,你写的
x mod 2是非法语法,正确写法为xmod2或者前缀形式mod x 2。 - 递归返回值处理错误:
split xs返回的是存储奇偶列表的二元组,你直接将x和二元组用:拼接完全不符合类型要求,同时你把拼接结果用[]包裹会生成嵌套列表,和函数返回值类型不匹配。 - 守卫逻辑冗余:你已经覆盖了
mod 2 == 0和mod 2 /= 0两种全部可能的情况,otherwise分支永远不会执行,属于无效代码。
正确实现
递归实现版本
split :: Integral a => [a] -> ([a], [a]) split [] = ([], []) split (x:xs) | even x = (odds, x : evens) | otherwise = (x : odds, evens) where (odds, evens) = split xs
这里先递归处理剩余列表得到二元组(odds, evens),再根据当前元素的奇偶性,把元素加到对应列表的头部即可。
高阶函数简化版本
你也可以直接用标准库的partition函数实现,代码更简洁:
import Data.List (partition) split :: Integral a => [a] -> ([a], [a]) split = partition odd
partition函数会返回两个列表,第一个是所有满足条件的元素,第二个是不满足条件的元素,这里用odd作为判断条件,返回的第一个列表就是奇数列表,第二个是偶数列表,完全符合需求。
内容的提问来源于stack exchange,提问作者PaladinPlague
相关产品推荐
相关产品推荐

