Function 如何调用函数模式以获得应用函数的第一个非空结果?

Function 如何调用函数模式以获得应用函数的第一个非空结果?,function,functional-programming,Function,Functional Programming,函数是否有一个“规范”名称: 接收一个集合和一个函数 迭代集合 对于每个元素,调用函数 如果函数返回非null值,则停止迭代并返回该值 否则继续 理想情况下,每个元素最多只能调用一次“函数” 示例实现(感觉有点笨拙) 这听起来像是可以实现一个类似于firstThat的函数,其中first将一个集合和一个返回布尔值的函数作为参数,并返回满足谓词的第一个元素。在哈斯克尔 firstThat :: (a -> Bool) -> [a] -> a firstThat f (x:xs

函数是否有一个“规范”名称:

  • 接收一个集合和一个函数
  • 迭代集合
  • 对于每个元素,调用函数
  • 如果函数返回非null值,则停止迭代并返回该值
  • 否则继续
理想情况下,每个元素最多只能调用一次“函数”

示例实现(感觉有点笨拙)


这听起来像是可以实现一个类似于
firstThat
的函数,其中first将一个集合和一个返回布尔值的函数作为参数,并返回满足谓词的第一个元素。在哈斯克尔

firstThat :: (a -> Bool) -> [a] -> a
firstThat f (x:xs)
   | f x == True = x --returns the item
   | otherwise = first f xs

这不是您要寻找的100%,但可以修改以完成任务(在您选择的语言中,当然有
null
值!)。

正如您已经发现的,它可以分解为常见模式“查找满足谓词的集合中的第一个元素”在几乎任何语言中都有函数(如,FordIf,在C++中或<代码>查找Haskell中的< /COD>),然后它可以与另一个辅助函数组合使用所传递函数的结果,就像在这个Haskell片段中:

firstApply :: (a -> Maybe b) -> [a] -> Maybe b
firstApply f = fmap f . find (isJust . f)
--or
firstApply f = join . find isJust . map f
--or
firstApply f = mconcat . map f
如果没有这一点,您也可以像@zcleghern那样手动完成任务。命令式变体也符合此描述,不同之处仅限于实现。在大多数命令式语言中,您可能会使用循环遍历集合,使用纯函数式的递归遍历集合

您的实现是两种方式的混合:高阶
find
和来自FP的闭包(res)、可变引用和来自IP的手动案例处理


了解了很多关于FP的知识,你也可以用更一般或抽象的方法来描述任务(例如,这个函数可以被认为是反同构或折叠的特例),但我想这可能是一个不必要的过度复杂。

好吧,类型“b”可以替换为(可能是“b”)或者什么的,我猜……但是对大多数人来说,“first”是“集合的第一个元素”的意思,不是吗?是的,我会编辑我的答案以便在这方面更清楚一点。我想一个更好的名字可能是first。是的,你可以检查返回值是否只是一些东西。只是为了确保,“f”函数在某些y中不应用两次吗我们的例子?(我将编辑我的问题以澄清我试图避免它。)@phtrivier仅在第一个例子中。
firstApply :: (a -> Maybe b) -> [a] -> Maybe b
firstApply f = fmap f . find (isJust . f)
--or
firstApply f = join . find isJust . map f
--or
firstApply f = mconcat . map f