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

mar*_*iop 8 haskell

我有一个与Data.List和deleteBy的签名有关的问题.理想情况下,此函数应该输入谓词并删除谓词为true的第一个元素.就像是:

deleteBy :: (a -> Bool) -> [a] -> [a]
deleteBy p = go
    where go []                   = []
          go (x:xs) | p x         = xs
                    | otherwise   = x:go xs
Run Code Online (Sandbox Code Playgroud)

相反,库中定义的函数同时使用谓词和值:

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
Run Code Online (Sandbox Code Playgroud)

很容易看出它eq总是x作为第一个参数使用并且x被修复deleteBy,所以没有理由得到两个eqx不是eq x.相反,通过对单个元素进行谓词处理,您可以传递不比较两个值的谓词,例如对类型的一部分a起作用的函数或者像这样的普通函数cons true.我的问题是:为什么deleteBy以这种方式实施?

cdk*_*cdk 11

deleteBy函数是一个概括delete,因此delete首先看一下是有帮助的.

delete :: Eq a => a -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

delete取值Eq a => a,然后删除该值的第一次出现从[a]使用(==)来自Eq实例.

Data.List中的所有*By函数一样,Eq约束被删除,程序员需要提供自己的替换(==)函数.

因此,删除Eq约束delete并将其替换为类型(==),即a -> a -> Bool,为您提供类型deleteBy.

换句话说,它是为了与其他*By操作保持一致Data.List.