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

How do you call the functional pattern to get first non null result of applying function?

是否有一个函数的 'canonical' 名称:

理想情况下,每个元素最多应调用 'function' 一次。

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

// xs : collection of type 'a
// f  : function from type 'a to type 'b
// returns : an element of type 'b, or nothing
function what_is_in_a_name(xs, f) {
  var res = null;
  _.find(function (item) {
    res = f(item);
    return res !== null;
  });
  return res;
}

这听起来好像可以实现类似于 firstThat 之类的函数,其中首先将一个集合和一个 returns 布尔值函数作为参数,并且 returns满足谓词的第一个元素。在 Haskell、

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

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

正如您已经发现的那样,它可以分解为通用模式“找到满足谓词的集合中的第一个元素”,几乎任何语言都有一个函数(例如,find_if 在 C++ 中或 find 在 Haskell 中)。然后它可以与另一个辅助函数结合使用传递函数的结果,就像这个 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 了解很多,您也可以根据更一般或更抽象的方式来制定任务(例如,此函数可以被视为变形或折叠的特例),但我想它会是不必要的复杂化。