【问题标题】:F# String to numeric parse. Incomplete pattern matches on this expressionF# 字符串到数值解析。此表达式的不完整模式匹配
【发布时间】:2019-08-06 19:55:09
【问题描述】:

在 F# 中创建命令行菜单时出错。函数本质上应该将 char(string) 转换为 num 并运行 = 代码。

Module Main = 
    let rec commandmenu() = 
       printfn "Select a command"
       printfn "1. Word count Command - Word count"
       printfn "2. Word count Command help"
       printfn "3. Touch Command - Touch file"
       printfn "4. Touch Command help"
       printfn "5. Version"
       printfn "6. Quit"
       printfn "--------------------------------"
       printfn "Select option (Eg '1','5') "


       let optionselect = Console.ReadLine()
       match System.Int32.TryParse optionselect with
       | (true, number) when number = 1
                        -> wordcount()
                          // printf"Press any key to continue"
       | (true, number) when number = 2
                        -> wordcounthelp()

       | (true, number) when number = 3
                        -> touch()

       | (true, number) when number = 4
                        -> touchhelp()

       | (true, number) when number = 5
                        -> version()
       | (true, number) when number = 6
                        -> 0   //Exit code

我不希望我的选项能够正常运行,因为它们还没有被正确编码,但是这个错误完全阻止了构建。当然包括开放系统。

【问题讨论】:

  • 仅供参考,您可以直接匹配数字文字,例如| (true, 1) -> wordcount()。您没有处理其他数字,或者布尔值是 false 的情况。
  • 您是否尝试过“模块”而不是您在此处显示的内容(“模块”)?
  • 假设带有大写 M 的 Module 是一个错字,ideone.com/zUXIdO 我必须添加虚拟函数,但这编译得很好。你有什么错误确切地
  • 你可以使用像 Argu 这样的命令行库或其他东西。

标签: f# tryparse


【解决方案1】:

不完整的模式匹配错误表示没有考虑到匹配表达式 (System.Int32.TryParse optionselect) 的所有可能性。在这种特殊情况下,有两个重要原因。

  1. 没有考虑到 TryParse 产生 false 作为返回元组的第一个值的可能性。
  2. 由于返回元组的第二个值是 Int32,因此您必须考虑 Int32 可以具有的所有其他可能值,无论是显式还是默认情况下(使用通配符表示 Int32 值)。

我不知道您正在调用的各个函数的作用,但添加通配符模式作为贯穿案例并简单地递归调用 commandmenu 可能就足够了。

正在添加...

       | _ -> commandmenu ()

...可能就够了。

附带说明:对于每种情况,您都不需要使用 when 的保护子句。只需将实际值 1,2 等替换为 number 绑定即可。例如

| (true, 1) -> wordcount()

【讨论】:

  • 这解决了我的问题,谢谢,是其他没有解决的可能性导致了这个问题,你推荐的代码减少也让我的代码更干净,再次感谢。我的退出选项有一点问题,但这与我的问题无关。完美解释的答案。
  • @user4999318 在这种情况下,您应该接受答案。
【解决方案2】:

这显然属于家庭作业的范畴,因此解决编码问题而不是具体问题是有意义的。随着编码问题的解决,该问题将消失,因此我将间接解决具体问题。

示例中有重复的代码。重复的代码就是我们所说的代码异味,并且经常表明有问题。重复的代码如下所示。

| (true, number) when number = <<some number>>

在这种情况下,重复是尝试同时执行两项任务的结果,而不是将逻辑分解成更小的部分。第一步应该是将字符串转换为数字。为此,我们可以简单地创建一个函数。

let tryParse s =
    match Int32.TryParse s with
    | true, i -> Some i
    | false, _ -> None

结果是Some nNone。然后我们可以匹配这两个,然后在Some n 的分支中继续匹配n。在这种情况下,一个可能更好的选择是匹配 Some 1Some 2 等,这使得当 n 为一个我们不感兴趣的数字。像这样。

let optionselect = Console.ReadLine()
match tryParse optionselect with
| Some 1 -> something1 ()
| Some 2 -> something2 ()
| _ -> somethingOther () // another number, or not parsable

如果您想处理这个可能的其他号码,无论它是什么,您都应该在末尾匹配 Some nNone,而不仅仅是在通配符上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    相关资源
    最近更新 更多