F# 将一个参数输送到多个函数?

F# 将一个参数输送到多个函数?,f#,F#,如何将一个参数传递到多个函数?例如,如果我希望将元组2,5同时传递给fst和snd,然后将每个元组的结果作为两个参数传递给另一个函数,则可以使用以下假设的、非工作的代码来说明: 2,5 |>fst&snd |>addUpnr1,nr2那么让我们从一个更好的例子开始……猜猜你想要什么 让我们这样定义add…使它显式地在2元组上运行…而不是curry let addUp : (int * int) -> int = fun (x,y) -> x + y 你想去,让我们说吧 le

如何将一个参数传递到多个函数?例如,如果我希望将元组2,5同时传递给fst和snd,然后将每个元组的结果作为两个参数传递给另一个函数,则可以使用以下假设的、非工作的代码来说明:
2,5 |>fst&snd |>addUpnr1,nr2

那么让我们从一个更好的例子开始……猜猜你想要什么

让我们这样定义add…使它显式地在2元组上运行…而不是curry

let addUp : (int * int) -> int =
    fun (x,y) -> x + y
你想去,让我们说吧

let z = (2,4)|> (fun (x,y) -> 2*x,y) |> addUp
这很难看

但请注意,我们正在创建一个转换两个元组的管道,然后对其应用一些函数

现在,tuple是一个函子…这意味着当我们得到一个对tuple中的类型进行操作的函数时,我们可以将它转换为一个对整个tuple进行操作的函数

2元组是一个两次以上的函子

module TupleFst = 
    let map : ('a -> 'b) -> ('a * 'c) -> ('b * 'c) = 
        fun f (x,y) -> (f x, y)
module TupleSnd = 
    let map : ('a -> 'b) -> ('c * 'a) -> ('c * 'b) = 
        fun f (x,y) -> (x,f y)
我已经用签名定义了它们,让它清楚地表明发生了什么

在TupleFst中,我们取一个作用于元组的第一个元素的函数,然后将其提升为作用于映射第一个元素的整个元组的函数

在TupleSnd中,我们处理tuple的第二个成员

现在我们可以把这个例子写成

let z = (2,4)|> TupleFst.map ((*) 2) |> addUp
这更好吗?…值得商榷…在这个小例子中,它可能会让生活变得更糟,但原理就在那里…如果你看一下函数和应用程序,它有更多的内容…它可以应用于各种数据结构

我认为这个包使用了从Haskell偷来的相同语法,我认为您可以在这里编写上述内容:

let z = ((*) 2) <!> (2,4) |> addUp
但是我还没有安装它,并且所有这些都可以工作…所以上面可能有一个输入错误啊…我不知道如何告诉FSharpPlus从哪个函子中选择映射…所以上面是不明确的,可能无法编译…你当然可以定义自己的操作符而不是映射

let (<!>) = TupleFst.map
let (<!!>) = TupleSnd.map
let z1 = ((*) 2) <!> (2,4) |> addUp
let z2 = ((*) 2) <!!> (2,4) |> addUp
这确实可以编译!对元组中的第一个元素进行操作!!在第二个……我不确定!!是一个合理的名字…同时!是惯用的…但不管怎样


在这种情况下,这完全是过火了!。。。其他答案更好…我想我是想证明,如果你在一个提升的世界里工作,在这里,元组,你通常可以隐藏铅锤。

所以让我们从一个更好的例子开始…猜猜你在追求什么

让我们这样定义add…使它显式地在2元组上运行…而不是curry

let addUp : (int * int) -> int =
    fun (x,y) -> x + y
你想去,让我们说吧

let z = (2,4)|> (fun (x,y) -> 2*x,y) |> addUp
这很难看

但请注意,我们正在创建一个转换两个元组的管道,然后对其应用一些函数

现在,tuple是一个函子…这意味着当我们得到一个对tuple中的类型进行操作的函数时,我们可以将它转换为一个对整个tuple进行操作的函数

2元组是一个两次以上的函子

module TupleFst = 
    let map : ('a -> 'b) -> ('a * 'c) -> ('b * 'c) = 
        fun f (x,y) -> (f x, y)
module TupleSnd = 
    let map : ('a -> 'b) -> ('c * 'a) -> ('c * 'b) = 
        fun f (x,y) -> (x,f y)
我已经用签名定义了它们,让它清楚地表明发生了什么

在TupleFst中,我们取一个作用于元组的第一个元素的函数,然后将其提升为作用于映射第一个元素的整个元组的函数

在TupleSnd中,我们处理tuple的第二个成员

现在我们可以把这个例子写成

let z = (2,4)|> TupleFst.map ((*) 2) |> addUp
这更好吗?…值得商榷…在这个小例子中,它可能会让生活变得更糟,但原理就在那里…如果你看一下函数和应用程序,它有更多的内容…它可以应用于各种数据结构

我认为这个包使用了从Haskell偷来的相同语法,我认为您可以在这里编写上述内容:

let z = ((*) 2) <!> (2,4) |> addUp
但是我还没有安装它,并且所有这些都可以工作…所以上面可能有一个输入错误啊…我不知道如何告诉FSharpPlus从哪个函子中选择映射…所以上面是不明确的,可能无法编译…你当然可以定义自己的操作符而不是映射

let (<!>) = TupleFst.map
let (<!!>) = TupleSnd.map
let z1 = ((*) 2) <!> (2,4) |> addUp
let z2 = ((*) 2) <!!> (2,4) |> addUp
这确实可以编译!对元组中的第一个元素进行操作!!在第二个……我不确定!!是一个合理的名字…同时!是惯用的…但不管怎样


在这种情况下,这完全是过火了!。。。其他答案更好……我想我是在试图证明,如果你在一个提升的世界中工作,那么元组,你通常可以隐藏管道。

管道操作符对于实现名称所暗示的功能非常有用-一个需要通过一系列转换传递一些输入的管道

如果您想要更复杂的数据流,那么只需使用正常机制通过F提供的程序传递数据,即可获得更好的结果,即变量:

let tuple = (2,5) 
let nr1 = fst tuple
let nr2 = snd tuple 
addUp nr1 nr2
如果碰巧使用元组,还可以使用模式匹配:

let tuple = (2,5) 
let nr1, nr2 = tuple
addUp nr1 nr2

您可以发明像|>这样的组合符和运算符来实现这一点,而不使用变量,但这违背了管道运算符的目的,即使代码更可读。

管道运算符对于实现名称所建议的功能非常有用-管道
(2, 5)
|> fun t -> first t, second t
||> addUp
您需要通过一系列转换传递一些输入的ine

如果您想要更复杂的数据流,那么只需使用正常机制通过F提供的程序传递数据,即可获得更好的结果,即变量:

let tuple = (2,5) 
let nr1 = fst tuple
let nr2 = snd tuple 
addUp nr1 nr2
如果碰巧使用元组,还可以使用模式匹配:

let tuple = (2,5) 
let nr1, nr2 = tuple
addUp nr1 nr2
您可以发明像|>这样的组合符和运算符来实现这一点,而不使用变量,但这违背了管道运算符的目的,即使代码更具可读性

(2, 5)
|> fun t -> first t, second t
||> addUp
第二行将输入元组传递给第一个和第二个函数,并将它们的组合结果作为新元组返回

这是假设addUp接受两个常规参数,而不是元组。如果需要一个元组,则在最后一行使用常规管道操作符|>

完整示例:

let first (a, b) = a * b
let second (a, b) = a ** b
let addUp a b = a + b

let answer =
    (2.0, 5.0)
    |> fun t -> first t, second t
    ||> addUp

// answer is 42.0
第二行将输入元组传递给第一个和第二个函数,并将它们的组合结果作为新元组返回

这是假设addUp接受两个常规参数,而不是元组。如果需要一个元组,则在最后一行使用常规管道操作符|>

完整示例:

let first (a, b) = a * b
let second (a, b) = a ** b
let addUp a b = a + b

let answer =
    (2.0, 5.0)
    |> fun t -> first t, second t
    ||> addUp

// answer is 42.0


你的问题对我来说毫无意义。你想在假设的例子中实现的东西可以通过模式匹配来实现:让a,b=两个值加起来a,b2,5 |>加起来回答这个例子…虽然不是问题我想知道你想的是不是像镜头一样的东西…谷歌它…关于转换记录你的问题对我来说没什么意义。你想在你假设的例子中实现的东西可以通过模式匹配来实现:让a,b=addUp a,b2,5 |>addUp中的两个值来回答这个例子…虽然不是这个问题,但我想知道你想的是不是像镜头一样的东西…google it…关于转换记录fun t->first t,第二个t…只是id函数…它什么都不做?@MrD first和second是以元组作为参数的函数。有趣的t->first t,second t是一个函数,它接受一个元组,首先使用该元组调用,然后使用同一个元组调用第二个,并返回组成元组的两个函数的结果。@MrD啊,我相信你在考虑fst和snd,这当然会使该行的行为类似于id。我更改了它们以避免这种混淆,但我想我做的不是很好-啊哈…我在我的答案中把它改成了更有趣的东西…所以我得到了jist…也就是说,函数是什么并不重要…只要它是一个在元组上运行的管道,你就可以对它应用函子逻辑。也许我会用我的代码直接回答这个问题,看看它是否仍然有效,第二个t…只是id函数…它什么都不做?@MrD first和second是以元组作为参数的函数。有趣的t->first t,second t是一个函数,它接受一个元组,首先使用该元组调用,然后使用同一个元组调用第二个,并返回组成元组的两个函数的结果。@MrD啊,我相信你在考虑fst和snd,这当然会使该行的行为类似于id。我更改了它们以避免这种混淆,但我想我做的不是很好-啊哈…我在回答中把它改成了更有趣的东西…所以我得到了jist…即函数是什么并不重要…只要它是一个在元组上运行的管道,你可以对它应用函子逻辑,也许我会用我的代码直接回答这个问题,看看它是否仍然有效……嗯……我同意可读性和简洁性之间存在着紧张关系……当你想挥手隐藏铅管时,这是一个关键点……特别是如果铅管在任何地方都有效,例如计算表达式单子上的无点糖…我们选择隐藏铅垂mmmm…我同意可读性和简洁性之间存在紧张关系…当你想挥手隐藏铅垂时有一点…特别是如果铅垂无处不在,例如计算表达式实际上是单子上的无点糖…我们选择隐藏管道