Haskell的Data.Function.on是做什么的?

3gtaxfhh  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(108)

我发现很难在Haskell中找到on的例子,我不明白Haskell的Data.Function页面上的解释。请问,我可以有它的使用示例和使用它使解决方案更简单或更有效的问题/代码示例吗?

s3fp2yjn

s3fp2yjn1#

假设我们有一个有两个参数的函数f,我们需要一个类似的函数来充当f,但只有在它的两个参数都被另一个函数g修改之后。
我们可以重新定义

new_f x y = f (g x) (g y)

字符串
或者利用on

new_f = f `on` g


很好,后者可以直接使用,而不需要定义新的符号new_f。(使用lambda也是可行的,但没有那么好)
这通常与compare一起使用,compare是一个库二进制函数,用于检查其两个参数之间的顺序。

sortBy (compare `on` name)   somePeopleList
sortBy (compare `on` age)    somePeopleList
sortBy (compare `on` height) somePeopleList
...


根据不同的标准进行排序。上面,我们假设name等是可以从人中提取相关信息的函数。
(In更现代的Haskell,我们也有sortBy (comparing age) somePeopleList,甚至sortOn age somePeopleList用于相同的任务)

xkrw2x1b

xkrw2x1b2#

on的类型签名是

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

字符串
而且,实际上,这个函数只有一个合理的(非底部)实现。

f `on` g = \x y -> f (g x) (g y)


或者,像GHC源代码中那样用中缀参数编写,

(.+.) `on` g = \x y -> g x .+. g y


所以函数的主体相当简单。问题是:我们为什么要关心。
根据我的经验,on最常见的用例是用compare扩充排序或比较函数。
在Python中,如果我们想根据人名对一个人的列表进行排序,我们可以这样写:

my_list.sort(key=lambda person: person.name)


Haskell的sortBy采用一个比较函数进行排序,所以我们在Haskell中编写相同的函数,如下所示:

sortBy (\x y -> getName x `compare` getName y) myList


但那只是on。所以实际上

sortBy (compare `on` getName) myList


“按名称比较排序”。它实际上读起来 * 几乎 * 像英语。
现在,特别是对于排序来说,这种范例非常常见,以至于最近的Haskell版本提供了sortOn,它接受Python风格的key参数

sortOn getName myList


但是有一个完整的“By”函数集合可以在列表上工作,Haskell开发人员并没有为每个函数编写“On”变体。
以下是一些示例:

-- Remove entries which have the same name as someone else
nubBy ((==) `on` getName) someList
-- Insert into a list sorted by salary, preserving the ordering
insertBy (compare `on` getSalary) newEmployee employees
-- Find the student with the highest grade
maximumBy (compare `on` getGrade) myStudents


因此,通常,on将与名称以“By”结尾的函数一起使用。

cetgtptt

cetgtptt3#

作为对现有答案的补充,从一些理论家的Angular 来看,Haskell的Data.Function.on是一些人称之为psi combinator的实现。引用Smullyan <$:
一只psi鸟是一只满足以下条件的鸟:
[2] Raymond M. Smullyan,To mock a mockingbird,Oxford University Press,2000.

相关

相关问题