Haskell中如何将Eq/Ord类比较函数作为参数传入其他函数
问题排查与解决方法
比较运算符属于普通的高阶函数,完全可以作为参数传递给其他函数,你遇到的编译错误由以下几个基础问题导致:
- 类型变量不统一:你定义的bar签名
bar :: (a -> a -> Bool) -> [x] -> [x]中,a和x是两个独立的泛型参数,编译器无法确认传入的比较函数可以操作列表的x类型元素,需要将二者统一为同一类型变量,修改为bar :: (a -> a -> Bool) -> [a] -> [a]即可。 - 缺少必要的类型约束:foo函数中需要对列表元素和0做大小比较、判等操作,说明列表元素必须同时属于
Num(支持0常量)和Ord(支持大小比较,Ord类型类已默认包含Eq类型类的约束)类型类,因此foo的签名需要添加对应约束,修改为foo :: (Ord a, Num a) => [a] -> [a]。 - 空列表安全隐患:直接调用
head x读取首元素,如果传入空列表会触发运行时错误,建议优先用模式匹配处理非空情况。
修正后的可运行代码示例
-- bar的示例实现,可替换为你自己的业务逻辑 bar :: (a -> a -> Bool) -> [a] -> [a] bar func x = filter (func 0) x -- 处理了空列表、添加了类型约束的foo函数 foo :: (Ord a, Num a) => [a] -> [a] foo [] = [] -- 空列表兜底逻辑,可按需调整 foo arr@(first:_) | first < 0 = bar (<) arr | first == 0 = bar (==) arr | otherwise = bar (>) arr
内容的提问来源于stack exchange,提问作者CoffeeKid
相关产品推荐
相关产品推荐

