我有一个与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
,所以没有理由得到两个eq
而x
不是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
.