【问题标题】:Point-free for filter function无点过滤功能
【发布时间】:2019-05-20 07:29:48
【问题描述】:

filter 函数是否存在一个无点函数来查找列表中第一个元素对的最小值?例如:

findMinimum xs =  filter ((== minimum (map fst xs)) . fst ) xs

-- example:
findMinimum [(0, 0), (0, 1), (2, 2), (3, 2), (1, 4)] = [(0, 0), (0, 1)]

如何将findMinimum 函数转换为无点函数:

findMinimum = ??

【问题讨论】:

  • 每个函数都可以写成无点形式;问题是,无点形式是否比有指向的等价形式更好?

标签: haskell filtering pointfree tacit-programming


【解决方案1】:

pointfree.io 输出这个,还不错。不过,我还是更喜欢原始代码。

findMinimum = filter =<< (. fst) . (==) . minimum . map fst

【讨论】:

  • 是的,这还不错,我更喜欢无积分版本并投票赞成。是否存在更具可读性的答案?
  • @JoeChoi 我认为没有比这更好的了,因为你有两次出现xs,所以需要&gt;&gt;= 或&lt;*&gt; 之类的东西来“复制”隐式参数。使用&lt;*&gt; 似乎会导致更糟糕的代码,IMO。
  • @JoeChoi 可能只使用可选的括号 filter =&lt;&lt; ((. fst) . (==) . minimum . map fst),以使分组更加直观。
【解决方案2】:

不同的实现

head . groupBy ((==) `on` fst) . sortOn fst

首先排序和分组,选择第一个子列表。也许您可能想明确处理空列表。

【讨论】:

  • 当然,这会将一对 O(n) 遍历替换为 O(n lg n) 排序。
  • 很好的答案,谢谢。为了处理空列表的需要,我对其进行了一些修改:concat . take 1 . groupBy ((==) on` fst) 。排序 fst`。它希望作为公认的答案。
  • 我认为不是 O(n log n)(非正式地使用 O)。
【解决方案3】:

将这对放在Arg 中,您可以对第一个元素进行排序,您可以按如下方式利用它:

import Data.Semigroup (Arg(..))
import Data.Ord (comparing)

findMinimum :: Ord a => [(a, b)] -> (a, b)
findMinimum = minimumBy (comparing (uncurry Arg))

【讨论】:

  • 谢谢。我投票支持comparing (uncurry Arg) 以提供另一种方式来做到这一点,如comparing fst。但是findMinimum 以[(a,b)] 而不是(a, b) 返回对列表。
猜你喜欢
  • 2012-03-26
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2023-03-24
相关资源
最近更新 更多