有一个代码:
//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
我理解这些功能应该产生相同的结果,但结果有很大的不同。谁能解释一下呢?
P.S。简化示例:
let test = [|1..10|]
let res = test
|> Array.sum
|> (/) 5
我希望test = 11(sum(1..10)= 55然后是55/5)但是在Array.sum管道不能正常工作之后(结果test = 0)。
答案 0 :(得分:5)
另一种方法是使用反向管道运算符(< |),以便(/)的部分应用程序以正确的顺序使用参数完成:
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是某个值。反向管道看起来不是很多,但在某些情况下它可以帮助清理一些代码。
答案 1 :(得分:4)
您似乎误解了中缀函数中的参数顺序。
您可以按如下方式扩展无点表格:
x |> (/) 5
<=> (/) 5 x
<=> 5 / x
所以这与你的期望相反。它仅适用于(+)
,(*)
等交换函数。如果您热衷于无点样式,flip
函数有助于与{{1}一起使用}:
|>
答案 2 :(得分:1)
/
运算符无法按照您的假设运行。您只需要更明确一点,并将error2中的最后一行更改为
fun t -> t/2.0
然后它应该全部工作。
这个问题的答案是4分。这里是赠品。
编辑:要了解/
在|>
处发生了什么,请考虑展开a |> (/) b
((/) b) a //by removing |>
a / b //what happens when / is reinterpreted as a function
时会发生什么
以下都是等效的
{{1}}