内置f#操作符,用相同的输入但不同的输出组合函数? [英] Built in f# operator to compose functions with the same input but different outputs?

查看:78
本文介绍了内置f#操作符,用相同的输入但不同的输出组合函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道< 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

code>


解决方案

向后组合运算符(<< code>被定义为:

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

应用两个谓词时,它实际上是一个函数,其初始值为'a 返回'c ,而处理'b 的值里面。



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



放弃(第一个)谓词返回的值,然后返回原始参数。这样的操作符存在于WebSharper中:

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

我喜欢这种方式,因为:


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

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

  let(|> !!)xf = ignore(fx); x 

对两个谓词应用参数,返回结果元组,完全和你自己的例子一样。有这样的操作员OCaml,很容易适应F#:
$ b $ pre> val(&&& amp; amp;):('a - > ;'b) - > ('a - >'c) - > 'a - > 'b *'c

正如@JackP所注意到的,&&& amp ; 在F#中已经被定义为另一个用途,所以让我们使用另一个名字:

  ///将两个函数应用于相同的参数。 
let(。& ;.)f g x =(f x,g x)

//用法
let ret1,ret2 =
x
|> (f。& g)

以上样本适用于函数应用程序的顺序。如果您需要以相反顺序申请,则需要相应地修改代码。


I understand the << compose operator takes two functions that both take in and return the same type. e.g. (lhs:'a -> 'a) -> (rhs:'a -> 'a) -> 'a

I often find myself wanting something like (lhs:'a -> 'b) -> (rhs:'c -> 'b) -> 'b in cases where I'm interested in side affects and not the return value 'b is probably the unit type. This is only when I have two lines in succession where I'm persisting something to a database.

Is there a built in function or idiomatic F# way of doing this without writing something like

let myCompose lhs rhs arg =
    lhs arg
    rhs arg

解决方案

Backward composition operator (<<) is defined as:

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

With two predicates applied, it is actually a function that takes initial value of 'a returning 'c, while the value of 'b is processed inside.

From the code sample you provided, let me assume that you need applying an argument to both predicates. There are several ways to do this:

Discarding the value returned by the (first) predicate, returning the original argument instead. Such operator exists in WebSharper:

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

I like this approach because:

  • it does not complicate things; each function application is atomic, and the code appears more readable;
  • it allows chaining throughout three or more predicates, like in the example above;

In this case, f must return unit, but you can easily work this around:

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

Applying the argument to both predicates, returning a tuple of results, exactly as in your own example. There's such operator OCaml, easy to adapt to F#:

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

As @JackP noticed, &&& is already defined in F# for another purpose, so let's use another name:

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

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

Note The samples above are for straight order of function application. If you need them applied in a reverse order, you need to modify the code accordingly.

这篇关于内置f#操作符,用相同的输入但不同的输出组合函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆