如何在 F# 中调用 bool.TryParse
How does one call bool.TryParse in F#
我需要在 F# 中调用 bool.TryParse,但我在使用编译器/Ionide 时遇到了一些困难。
例如
let value = true
let parsable = bool.TryParse("True", &value)
There error I'm seeing in Ionide for VSCode looks like the following.
val value : bool Full name:
value
Assembly: example3
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'F#
Compiler(1)
这是我在 F# 中使用 ref 关键字调用和语法的第一个示例,所以我不确定我做错了什么,byrefs 文档似乎也不是对理解这种特殊情况很有帮助。
事实证明,我在示例中遗漏的主要内容是 value
不是可变的,因为在这种情况下调用时需要可变。
工作示例:
let mutable value = true
let parsable = bool.TryParse("True", &value)
这个解决方案是在阅读了与 Span<T>
相关的 slightly related GitHub issue 之后想到的,然后也在 dotnet fsi
中玩了一下,这至少给了我以下线索。
let parsable = bool.TryParse("True", &value);;
-------------------------------------^^^^^^
stdin(34,38): error FS3230: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'
然而,事实证明,F# 似乎在 Try-Parse pattern 周围也有语法糖,我在进一步研究这个例子后开始回忆起来。这减少了调用 bool.TryParse
.
的以下替代解决方案
let value = true
let (parsable, _) = bool.TryParse "True"
或者无需绑定 parsable
并在单个表达式中指定默认值,以下示例可能更优雅。
let value = match bool.TryParse "True" with
| true, value -> value
| false, _ -> true
也许调用 bool.TryParse
和其他 Try-Parse 方法的不同方式各有利弊,但重要的是我找到了一些有效的解决方案,让我克服了最初的绊脚石缺少有关该主题的 F# 文档。
正如您已经发现的那样,可以通过将 'value' 设为可变变量来修复错误。
话说,你分享的最后一个解决方案(使用模式匹配)看起来是最好最安全的。
如果你碰巧做了很多这样的解析操作,我建议提取一些实用函数。这将避免错误地在 (true, value) 而不是 (false, value) 上进行正确的模式匹配。
示例代码:
open System
module Option =
let ofTry<'a> (res:(bool*'a)) : 'a option =
match res with
| true, res -> Some res
| false, _ -> None
module Result =
let ofTry<'a,'b> (err:'b) (res:(bool*'a)) : Result<'a, 'b> =
res
|> csharpToOption
|> Option.toResult err
module Samples =
let withPatternMatch =
match Int32.TryParse "5" with
| true, value -> value |> Some
| false, _ -> None
let withOptionHelper = Int32.TryParse "5" |> Option.ofTry
let withResultHelper = Int32.TryParse "5" |> Result.ofTry "Not a number"
我需要在 F# 中调用 bool.TryParse,但我在使用编译器/Ionide 时遇到了一些困难。
例如
let value = true
let parsable = bool.TryParse("True", &value)
There error I'm seeing in Ionide for VSCode looks like the following.
val value : bool Full name: value
Assembly: example3
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'F# Compiler(1)
这是我在 F# 中使用 ref 关键字调用和语法的第一个示例,所以我不确定我做错了什么,byrefs 文档似乎也不是对理解这种特殊情况很有帮助。
事实证明,我在示例中遗漏的主要内容是 value
不是可变的,因为在这种情况下调用时需要可变。
工作示例:
let mutable value = true
let parsable = bool.TryParse("True", &value)
这个解决方案是在阅读了与 Span<T>
相关的 slightly related GitHub issue 之后想到的,然后也在 dotnet fsi
中玩了一下,这至少给了我以下线索。
let parsable = bool.TryParse("True", &value);;
-------------------------------------^^^^^^
stdin(34,38): error FS3230: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'
然而,事实证明,F# 似乎在 Try-Parse pattern 周围也有语法糖,我在进一步研究这个例子后开始回忆起来。这减少了调用 bool.TryParse
.
let value = true
let (parsable, _) = bool.TryParse "True"
或者无需绑定 parsable
并在单个表达式中指定默认值,以下示例可能更优雅。
let value = match bool.TryParse "True" with
| true, value -> value
| false, _ -> true
也许调用 bool.TryParse
和其他 Try-Parse 方法的不同方式各有利弊,但重要的是我找到了一些有效的解决方案,让我克服了最初的绊脚石缺少有关该主题的 F# 文档。
正如您已经发现的那样,可以通过将 'value' 设为可变变量来修复错误。 话说,你分享的最后一个解决方案(使用模式匹配)看起来是最好最安全的。
如果你碰巧做了很多这样的解析操作,我建议提取一些实用函数。这将避免错误地在 (true, value) 而不是 (false, value) 上进行正确的模式匹配。
示例代码:
open System
module Option =
let ofTry<'a> (res:(bool*'a)) : 'a option =
match res with
| true, res -> Some res
| false, _ -> None
module Result =
let ofTry<'a,'b> (err:'b) (res:(bool*'a)) : Result<'a, 'b> =
res
|> csharpToOption
|> Option.toResult err
module Samples =
let withPatternMatch =
match Int32.TryParse "5" with
| true, value -> value |> Some
| false, _ -> None
let withOptionHelper = Int32.TryParse "5" |> Option.ofTry
let withResultHelper = Int32.TryParse "5" |> Result.ofTry "Not a number"