所以我试图在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“但这里有类型”字符串“”。如果有人知道如何使其正常工作(或者至少可以告诉我我需要做什么来将我的用户输入的值转换为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
在无效输入上抛出异常是不是更好地阻止您的应用程序在运行时爆炸?
由于我找不到任何返回int option
的函数,我写了一个:
let asInt32 numberString =
let (success,num) =
System.Int32.TryParse(numberString)
if success then
Some num
else
None
asInt32 "22"
(使用TryParse作为Gustavo建议)
我的建议是尝试使用F#函数,除非没有等效的F#函数。
其次,F#中的类型转换函数嵌入了System.(type).(Try)Parse
。 “Try
”这里是可选的,type
是任何数字类型,如int8
,...,int64
,float32
和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#之间跳转的原因是其他读者和你自己可能会感到困惑,因为这可能会使代码的可读性降低。