【问题标题】:How does F# pipeline operator workF# 管道运算符如何工作
【发布时间】:2013-09-23 23:59:10
【问题描述】:

有一个代码:

 //e = 1/2*Sum((yi -di)^2)
    let error y d =
        let map = 
            Array.map2 (fun y d -> (y - d) ** 2.0) y d
        let sum = 
            Array.sum map
        (sum / 2.0)

    let error2 y d =
        Array.map2 (fun y d -> (y - d) ** 2.0) y d
        |> Array.sum
        |> (/) 2.0

据我了解,这些函数应该产生相同的结果,但结果却有很大差异。谁能解释一下?

附言简化示例:

let test = [|1..10|]
    let res = test
                |> Array.sum
                |> (/) 5

我希望 test = 11 (sum(1..10) = 55 然后 55 / 5) 但在 Array.sum 管道无法按我想要的方式工作之后(结果 test = 0)。

【问题讨论】:

    标签: f# pipeline


    【解决方案1】:

    另一种选择是使用反向管道运算符 (

    let error2 y d =
        Array.map2 (fun y d -> (y - d) ** 2.0) y d
        |> Array.sum
        |> (/) <| 2.0
    

    编辑:看看这是否有助于澄清

    x/y = (/) x y = y |> (/) x = x |> (/) <| y
    

    所有这些都是等价的。管道运算符定义为:

    (|>) x f = f x
    (<|) f x = f x
    

    其中 f 是一个函数,x 是某个值。反向管道看起来作用不大,但在某些情况下它可以帮助清理一些代码。

    【讨论】:

      【解决方案2】:

      您似乎误解了中缀函数中的参数顺序。

      您可以将无点形式展开如下:

      x |> (/) 5
      <=> (/) 5 x
      <=> 5 / x
      

      所以这与您的预期相反。它只适用于(+)(*) 等可交换函数。如果您热衷于无点风格,flip 函数与|&gt; 一起使用会很有帮助:

      let inline flip f x y = f y x
      
      let error2 y d =
          Array.map2 (fun y d -> (y - d) ** 2.0) y d
          |> Array.sum
          |> flip (/) 2.0
      

      【讨论】:

        【解决方案3】:

        / 操作符不像你想象的那样工作。您只需要更明确一点,将 error2 中的最后一行更改为

        fun t -> t/2.0
        

        然后它应该一切正常。

        答案是 4 倍是这里的赠品。

        编辑:要了解/ 会发生什么,请考虑扩展|&gt; 时会发生什么

        以下都是等价的

        a |> (/) b
        ((/) b) a //by removing |>
        a / b     //what happens when / is reinterpreted as a function
        

        【讨论】:

        • 您是否想说它将被解释为b/a 而不是a/b
        • 最后一行应该是 "b / a" imo。我敢肯定 |> (op) x 是 f# 代码中 bug 的巨大来源;)
        猜你喜欢
        • 1970-01-01
        • 2017-05-25
        • 2010-11-30
        • 1970-01-01
        • 2010-12-24
        • 2020-07-09
        • 2012-02-12
        • 2016-02-21
        • 1970-01-01
        相关资源
        最近更新 更多