如何在 F# 的函数中使用用户输入的值

How can I use a user inputted value in my Function in F#

我试图在 F# 中创建一个简单的阶乘函数,它使用用户输入的值(使用控制台,我不知道这是否有任何区别)但我似乎找不到任何能够在我的函数中使用用户值的解决方案。

    open System

    let rec fact x =
        if x < 1 then 1
        else x * fact (x - 1)

    let input = Console.ReadLine()
    Console.WriteLine(fact input)

它经常给我这样的错误:“这个表达式应该有“int”类型,但这里有“string”类型”。如果有人对如何使其正常工作有任何想法(或者至少可以告诉我我需要做什么才能将用户输入的值转换为 INT,那将不胜感激。

F# 不会为您自动转换,因此您需要解析字符串:

open System

let rec fact x =
    if x < 1 then 1
    else x * fact (x - 1)

let input = Console.ReadLine()
Console.WriteLine(fact (Int32.Parse input))

理论上你需要转换回字符串才能打印它,但它之所以有效,是因为 Console.WriteLine 有一个重载,它接受一个整数并进行转换。

因为两者:

somevalue |> int

System.Int32.Parse somevalue

在无效输入时抛出异常不是更好地防止您的应用程序在运行时崩溃吗?

因为我找不到任何函数 returns int option 我写了一个:

let asInt32 numberString =
  let (success,num)  = 
    System.Int32.TryParse(numberString)
  if success then
    Some num
  else
    None
asInt32 "22"

(按照 Gustavo 的建议使用 TryParse)

我的建议是尝试使用 F# 函数,除非没有等效的 F# 函数。

其次,F# 中的类型转换函数中嵌入了 System.(type).(Try)Parse。这里的“Try”是可选的,type是任意数字类型,如int8,...,int64float32和float。 (最后一个是 64 位)

所以int "123" = System.Int32.Parse("123")是正确的。这两个函数是等价的。这也适用于浮点数。

第三,可以的话,尽量使用尾递归:

let fact n =
  let rec help acc = function
    | n when n <= 0 -> acc
    | n             -> help (acc*n) (n-1)
  help 1 n

let input = System.Console.ReadLine()
printfn "fact %s = %d" input (fact (int input))

如果我们输入 4 然后按回车键,输出将是:

fact 4 = 24

我不知道 F# 中是否有任何等同于 ReadLine 的东西。我找不到。

尝试坚持 F# 风格而不在 C# 和 F# 之间跳来跳去的原因是其他读者和您自己可能会感到困惑,因为这可能会降低代码的可读性。