F#创建具有多个函数的单个循环

Abr*_*000 3 f# loops

我刚刚开始深入研究一些编程并决定使用F#.作为练习,我试图将我在.bat中创建的脚本转换为F#.我在创建一个不止一件事的循环函数时遇到了麻烦.以下是此循环的旧脚本的代码.

:Select
cls
echo.
echo Which Game?
echo.
echo    1. Assassin's Creed
echo    2. Crysis
echo    3. Mass Effect
echo.
echo.
set/p "game=>"
if /I %game%==1 goto Creed
if /I %game%==2 goto Crysis
if /I %game%==3 goto Mass
echo.
echo Invalid selection!
echo.
echo.
pause
goto Select
Run Code Online (Sandbox Code Playgroud)

我试图在F#中为相同的函数创建的代码到目前为止看起来像这样:

let rec gameprint gameselect =
    printfn "Which Game?\n\n   1.%s\n   2.%s\n   3.%s\n\n\n" game1 game2 game3
    let mutable gameselect = Int32.Parse(stdin.ReadLine())
    if gameselect = "1" then game1
    elif gameselect = "2" then game2
    elif gameselect = "3" then game3
    else printf "temp"
    Console.Clear
Run Code Online (Sandbox Code Playgroud)

我知道我错过了一些东西,告诉它如果到达最后的"其他",它会再次运行; 我收到这些错误:

表达式应该具有类型'unit',但类型为'string'.使用'ignore'丢弃表达式的结果,或'let'将结果绑定到名称.

错误1此表达式应具有int类型,但此处的类型为字符串19 21

错误2此表达式应该具有int类型,但此处的类型为字符串20 23

错误3此表达式应该具有int类型,但此处的类型为字符串21 23

错误4此表达式应具有类型字符串,但此处具有类型单元22 17

警告5此表达式应为"unit"类型,但类型为"string".使用'ignore'丢弃表达式的结果,或'let'将结果绑定到名称.19 5

我更喜欢使用这样的方法(非常不完整):

let rec getGame() =
    match Int32.Parse(stdin.ReadLine()) with
    | 1 -> "Assassin's Creed"
    | 2 -> "Crysis"
    | 3 -> "Mass Effect"
    | _ -> printf "Temp"
Run Code Online (Sandbox Code Playgroud)

但是我得到了:

错误1此表达式应具有类型字符串,但此处具有类型单元36 19

而且我不确定如何将其循环并使其成为'printf'和'Console.Clear'

如果有一个我不了解的更实用的方法,我当然会喜欢学习:-)

提前致谢!

kvb*_*kvb 7

你第一次尝试的最大问题是,你解析从输入string到一个int,但你尝试模式对阵字符串.使用1,2并且,3而不是"1","2""3"将解决这个问题,但后来你会在大致相同的点作为你的第二次尝试.

你的第二次尝试几乎可以工作,但是F#告诉你你没有在所有分支中使用一致的返回类型:在前三种情况下你返回一个字符串,但在最后一种情况下你没有返回任何东西.在这种情况下,你需要做的只是循环,编译器会很高兴:

let rec getGame() =
    match Int32.Parse(stdin.ReadLine()) with
    | 1 -> "Assassin's Creed"
    | 2 -> "Crysis"
    | 3 -> "Mass Effect"
    | _ -> printf "Temp"; getGame()
Run Code Online (Sandbox Code Playgroud)

我会做更像这样的事情:

type Game = Creed | Crysis | Mass

let rec getGame() =
  printfn "Which Game?\n\n   1.%A\n   2.%A\n   3.%A\n\n" Creed Crysis Mass
  match stdin.ReadLine() |> Int32.TryParse with
  | true,1 -> Creed
  | true,2 -> Crysis
  | true,3 -> Mass
  | _ -> 
     printfn "You did not enter a valid choice."
     // put any other actions you want into here
     getGame()
Run Code Online (Sandbox Code Playgroud)