简体   繁体   English

为什么Haskell的Data.List.deleteBy接受输入比较函数(a - > a - > Bool)和值而不是谓词(a - > Bool)?

[英]Why Haskell's Data.List.deleteBy takes in input a comparison function (a -> a -> Bool) and a value instead of a predicate (a -> Bool)?

I have a question related to Data.List and the signature of deleteBy . 我有一个与Data.List和deleteBy的签名有关的问题。 Ideally this function should take in input a predicate and delete the first element for which the predicate is true. 理想情况下,此函数应该输入谓词并删除谓词为true的第一个元素。 Something like: 就像是:

deleteBy :: (a -> Bool) -> [a] -> [a]
deleteBy p = go
    where go []                   = []
          go (x:xs) | p x         = xs
                    | otherwise   = x:go xs

Instead the function defined in the library takes both a predicate and a value: 相反,库中定义的函数同时使用谓词和值:

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

It's easy to see that eq is always used with x as first argument and x is fixed in deleteBy , so there is no reason to get both eq and x instead of eq x . 很容易看出eq总是用x作为第一个参数而xdeleteBy是固定的,所以没有理由得到eqx而不是eq x On contrary, by taking a predicate working on a single element you can pass predicates that don't compare two values, such as a function that works on a part of the type a or a trivial function like cons true . 相反,通过对单个元素进行谓词处理,您可以传递不比较两个值的谓词,例如对类型a的一部分起作用的函数或者像cons true一样的普通函数。 My question is: why deleteBy has been implemented in this way? 我的问题是:为什么deleteBy已经以这种方式实现了?

The deleteBy function is a generalization of delete , so it's helpful to take a look at delete first. deleteBy函数是delete的泛化,因此首先看一下delete是有帮助的。

delete :: Eq a => a -> [a] -> [a]

delete takes a value Eq a => a , then deletes the first occurance of that value from the [a] using the (==) from the Eq instance. delete取值Eq a => a ,然后使用Eq实例中的(==)[a]删除该值的第一次出现。

As with all the *By functions in Data.List , the Eq constraint is removed and the programmer is required to provide their own replacement (==) function. Data.List中的所有*By函数一样 ,删除了Eq约束,并且程序员需要提供自己的替换(==)函数。

So removing the Eq constraint from delete and replacing it with the type of (==) , namely a -> a -> Bool , gives you the type of deleteBy . 因此从delete Eq约束并将其替换为(==)类型,即a -> a -> Bool ,为您提供deleteBy的类型。

In other words, it's for consistency with the rest of the *By operations in Data.List . 换句话说,它是为了与Data.List的其他*By操作保持Data.List

As cdk and others point out. 正如cdk和其他人指出的那样。 It is to generalize over the equality predicate. 它是对等式谓词的概括。

The function you are asking for is 'delete elements in the list which match this predicate'. 您要求的功能是“删除列表中与此谓词匹配的元素”。 This is more akin to single element filter . 这更像是单元素filter

The deleteBy function is 'delete element x, but use this comparison operator instead of (==) '. deleteBy函数是'delete element x,但使用此比较运算符而不是(==) '。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM