忽略函数的 F# 内联如何在副作用函数方面起作用
How F# inlining of ignore function works regarding side effect functions
我正在读这个 我想知道 ignore
函数是如何内联的:它的参数应该被丢弃但副作用仍然发生:
// See https://github.com/dotnet/fsharp/blob/main/src/fsharp/FSharp.Core/prim-types.fs
let inline (|>) x f = f x
let inline ignore _ = ()
// Side effect function returning a value to ignore
let ok () =
printfn "ok"
true
// Usage
let t1 = ok () |> ignore
// = ignore (ok ()) // `|>` inlined
// = () // `ignore` inlined
// what happened for `printfn "ok"` inside the `ok` function?
控制台输出:
ok
val ok : unit -> bool
val t1 : unit = ()
在 FSI 中执行代码时,编译时会打印“ok”(与 val ok : unit -> bool
之前出现的一样)。
→ 执行 .fs
文件中的代码会发生什么?
首先,F# interactive 的输出有点令人困惑 - 它在编译时没有 运行 函数。它首先编译代码,然后 运行s 它然后打印结果类型和所有结果的值。它需要 运行 打印前的代码,因为它还会打印最终值。
至于发生了什么,让我们看看如果您刚刚发生了什么:
let ok () = printfn "ok"; true
- 我们从
let t1 = ok () |> ignore
开始
- 内联
|>
后,这变成 let t1 = ignore(ok())
- 内联
ignore
后,这变成 let t1 = ok(); ()
- 现在您有一个使用
;
组成的表达式,因此 F# 计算第一个子表达式,即对 ok()
函数的调用。你得到 let t1 = (printf "ok"; true); ()
- 表达式是从左到右计算的,所以这个 运行 打印(执行副作用)并且 printf 的结果是一个单位值
()
。所以我们现在有 let t1 = ((); true); ()
.
- 现在,计算
;
运算符并丢弃 ()
。我们有 let t1 = true; ()
- 现在,计算第二个
;
运算符并丢弃 true
。我们有 let t1 = ()
。这就是最终结果!
我正在读这个 ignore
函数是如何内联的:它的参数应该被丢弃但副作用仍然发生:
// See https://github.com/dotnet/fsharp/blob/main/src/fsharp/FSharp.Core/prim-types.fs
let inline (|>) x f = f x
let inline ignore _ = ()
// Side effect function returning a value to ignore
let ok () =
printfn "ok"
true
// Usage
let t1 = ok () |> ignore
// = ignore (ok ()) // `|>` inlined
// = () // `ignore` inlined
// what happened for `printfn "ok"` inside the `ok` function?
控制台输出:
ok
val ok : unit -> bool
val t1 : unit = ()
在 FSI 中执行代码时,编译时会打印“ok”(与 val ok : unit -> bool
之前出现的一样)。
→ 执行 .fs
文件中的代码会发生什么?
首先,F# interactive 的输出有点令人困惑 - 它在编译时没有 运行 函数。它首先编译代码,然后 运行s 它然后打印结果类型和所有结果的值。它需要 运行 打印前的代码,因为它还会打印最终值。
至于发生了什么,让我们看看如果您刚刚发生了什么:
let ok () = printfn "ok"; true
- 我们从
let t1 = ok () |> ignore
开始
- 内联
|>
后,这变成let t1 = ignore(ok())
- 内联
ignore
后,这变成let t1 = ok(); ()
- 现在您有一个使用
;
组成的表达式,因此 F# 计算第一个子表达式,即对ok()
函数的调用。你得到let t1 = (printf "ok"; true); ()
- 表达式是从左到右计算的,所以这个 运行 打印(执行副作用)并且 printf 的结果是一个单位值
()
。所以我们现在有let t1 = ((); true); ()
. - 现在,计算
;
运算符并丢弃()
。我们有let t1 = true; ()
- 现在,计算第二个
;
运算符并丢弃true
。我们有let t1 = ()
。这就是最终结果!