f# - 内置 f# 运算符来组合具有相同输入但不同输出的函数?

标签 f# functional-programming

我理解 << compose 运算符采用两个函数,这两个函数都接受并返回相同的类型。例如(lhs:'a -> 'a) -> (rhs:'a -> 'a) -> 'a

在我感兴趣的情况下,我经常发现自己想要类似 (lhs:'a -> 'b) -> (rhs:'c -> 'b) -> 'b 的东西在侧面影响而不是返回值 'b 可能是单位类型。只有当我连续两行将某些内容保存到数据库时才会出现这种情况。

是否有内置函数或惯用的 F# 方法可以在不编写类似内容的情况下执行此操作

let myCompose lhs rhs arg =
    lhs arg
    rhs arg

最佳答案

向后组合运算符 (<<)定义为:

( << ) : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c`

应用了两个谓词,它实际上是一个函数,其初始值为'a。返回 'c , 而值 'b在内部处理。

根据您提供的代码示例,我假设您需要对两个谓词应用一个参数。有几种方法可以做到这一点:

丢弃(第一个)谓词返回的值,而是返回原始参数。这样的运算符存在于 WebSharper 中:

let ( |>! ) x f = f x; x
// Usage:
let ret =
    x
    |>! f1
    |>! f2
    |> f3

我喜欢这种方法,因为:

  • 它不会使事情复杂化;每个函数应用都是原子的,代码看起来更易读;
  • 它允许链接三个或更多谓词,如上例所示;

在这种情况下,f必须返回 unit ,但您可以轻松解决此问题:

let ( |>!! ) x f = ignore(f x); x

将参数应用于两个谓词,返回结果元组,与您自己的示例完全一样。有这样的算子OCaml,很容易适配F#:

val (&&&) : ('a -> 'b) -> ('a -> 'c) -> 'a -> 'b * 'c

正如@JackP 所注意到的,&&&已在 F# 中定义用于其他用途,因此让我们使用其他名称:

/// Applying two functions to the same argument.
let (.&.) f g x = (f x, g x)

// Usage
let ret1, ret2 =
   x
   |> (f .&. g)

注意 以上示例用于函数应用的直接顺序。如果您需要以相反的顺序应用它们,则需要相应地修改代码。

关于f# - 内置 f# 运算符来组合具有相同输入但不同输出的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17109624/

相关文章:

hash - 在 GetHashCode() 中使用 F# 的哈希函数邪恶?

c++ - 如何用 STL 实现替换这个 for 循环?

functional-programming - 用于进度报告的惯用 clojure?

scala - 使用 Scala 在功能上生成游戏 Action

f# - Option 的这种用法在 F# 中是惯用的吗?

f# - 如何避免多次迭代作为一种模式?

f# - F# 抽象类类型成员表达式可以是 "abstract override"吗?

.net - 解决 F# 中的接口(interface)冲突

C# Linq 合并两个字典

scala - Erlang 并发模型 vs Scala vs Go