[英]Why Haskell's Data.List.deleteBy takes in input a comparison function (a -> a -> Bool) and a value instead of a predicate (a -> Bool)?
我有一个与Data.List和deleteBy的签名有关的问题。 理想情况下,此函数应该输入谓词并删除谓词为true的第一个元素。 就像是:
deleteBy :: (a -> Bool) -> [a] -> [a]
deleteBy p = go
where go [] = []
go (x:xs) | p x = xs
| otherwise = x:go xs
相反,库中定义的函数同时使用谓词和值:
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
deleteBy _ _ [] = []
deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
很容易看出eq
总是用x
作为第一个参数而x
在deleteBy
是固定的,所以没有理由得到eq
和x
而不是eq x
。 相反,通过对单个元素进行谓词处理,您可以传递不比较两个值的谓词,例如对类型a
的一部分起作用的函数或者像cons true
一样的普通函数。 我的问题是:为什么deleteBy
已经以这种方式实现了?
deleteBy
函数是delete
的泛化,因此首先看一下delete
是有帮助的。
delete :: Eq a => a -> [a] -> [a]
delete
取值Eq a => a
,然后使用Eq
实例中的(==)
从[a]
删除该值的第一次出现。
与Data.List中的所有*By
函数一样 ,删除了Eq
约束,并且程序员需要提供自己的替换(==)
函数。
因此从delete
Eq
约束并将其替换为(==)
类型,即a -> a -> Bool
,为您提供deleteBy
的类型。
换句话说,它是为了与Data.List
的其他*By
操作保持Data.List
。
正如cdk和其他人指出的那样。 它是对等式谓词的概括。
您要求的功能是“删除列表中与此谓词匹配的元素”。 这更像是单元素filter
。
deleteBy
函数是'delete element x,但使用此比较运算符而不是(==)
'。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.