I’m just starting to dig into some programming and decided to go with F#. As practice, I was trying to convert a script I made in .bat into F#. I’m having trouble creating a looping function that does more than one thing. Here is the code from the old script for this loop.
: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
The code I’ve tried to make for the same function in F# looks like this so far:
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
I know I’m missing something that tells it to run again if it reaches the last “else”; and I’m getting these errors:
The expression should have type ‘unit’ but has type ‘string’. Use ‘ignore’ to discard the result of the expression, or ‘let’ to bind the result to a name.
Error 1 This expression was expected to have type int but here has type string 19 21
Error 2 This expression was expected to have type int but here has type string 20 23
Error 3 This expression was expected to have type int but here has type string 21 23
Error 4 This expression was expected to have type string but here has type unit 22 17
Warning 5 This expression should have type ‘unit’, but has type ‘string’. Use ‘ignore’ to discard the result of the expression, or ‘let’ to bind the result to a name. 19 5
I’d prefer to use an approach like this (Very incomplete):
let rec getGame() =
match Int32.Parse(stdin.ReadLine()) with
| 1 -> "Assassin's Creed"
| 2 -> "Crysis"
| 3 -> "Mass Effect"
| _ -> printf "Temp"
But I’m getting:
Error 1 This expression was expected to have type string but here has type unit 36 19
And I’m not sure how I would loop it and make it ‘printf’ and ‘Console.Clear’
If there is a more functional approach that I don’t know about, I would certainly love to learn 🙂
Thanks in advance!
The biggest problem with your first attempt is that you’re parsing the input from a
stringinto anint, but then you try to pattern match against strings. Using1,2, and3instead of"1","2", and"3"will fix that problem, but then you’ll be at roughly the same point as your second attempt.Your second attempt nearly works, but F# is telling you that you aren’t using a consistent return type across all of your branches: in the first three cases you’re returning a string but in the last case you’re not returning anything. All you need to do is loop in that case, and the compiler will be happy:
I’d do something more like this: