F# 如何要求用户在控制台F中再次播放#
好的,我现在正在fsharp的控制台中制作mastermind,我想知道如何询问用户是否想再次玩F# 如何要求用户在控制台F中再次播放#,f#,F#,好的,我现在正在fsharp的控制台中制作mastermind,我想知道如何询问用户是否想再次玩 let main() = choosePuzzleMaker() puzzleGuess() c <- guess b [([],(0,0))] while a <> c && d <> 8 do c <- guess b [(c, validate a c)] d <- d+1 if d <
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
但是,这不起作用,所以我的问题是:
您如何让控制台接受“是/否”的响应并使程序重新开始?看起来您的问题只是一个简单的缩进错误。与Python一样,F#通过缩进定义代码块。让我给你举个例子:
// Some variables
let x = 5
let y = 3
let z = 1
let add1_wrong x =
printfn "Adding 1 to %d produces..." x
printfn "The wrong answer: %d" (x + 1) // Oops! This is wrong
let add1_correct x =
printfn "Adding 1 to %d produces..." x
printfn "The right answer: %d" (x + 1) // This is correct
add1_wrong x
add1_wrong y
add1_wrong z
add1_correct x
add1_correct y
add1_correct z
尝试在F#Interactive中运行该命令,您将获得以下输出:
The wrong answer: 6
Adding 1 to 5 produces...
Adding 1 to 3 produces...
Adding 1 to 1 produces...
Adding 1 to 5 produces...
The right answer: 6
Adding 1 to 3 produces...
The right answer: 4
Adding 1 to 1 produces...
The right answer: 2
注意“错误答案:6”是如何在调用add1\u错误的函数之前立即打印出来的?从代码的编写方式来看,作者似乎打算将printfn“The error answer”
行放在add1\u error
函数内,但他犯了缩进错误,将其放在函数外。因此,它与设置x
、y
和z
变量的其余代码同时运行,并调用add1\u-error
和add1\u-right
如果您还不理解示例代码中的内容,现在就停止阅读,继续阅读直到理解为止。(如果在读了两三遍之后你仍然不理解它,或者问一个后续问题,因为这意味着我没有很好地解释它)。在继续之前,请务必在我的示例代码中看到缩进错误,因为您发布的代码中也有相同的错误。实际上,您有两个缩进错误,但其中只有一个导致了您所问的问题
这是您的main()
函数,与您在本问题中键入的函数完全相同,其中有两个缩进错误:
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
rec
关键字告诉F#编译器“我定义的函数将在某个时候直接或间接地调用它自己——因此请在函数本身中使用它的名称。”关键字和
创建一组函数,这些函数的名称彼此可用
因此,解决这个问题的一种方法是执行以下操作:
let rec PlayAgain() =
// ...
and main() =
// ...
这是可行的,但我推荐第二种解决方案。函数式编程的关键思想之一是将函数视为可以操作的“东西”。也就是说,您可以将函数存储在列表或数组中,将它们作为参数传递给其他函数,等等。这给我们带来了一种非常强大的技术,它可以让你的函数再次播放
函数变得更加通用和可重用。如果像playreach
这样的函数具有一般结构“进行一些计算或做出决定。然后,根据结果,下一步执行a或B”--那么您要做的就是为函数设置a和B参数!换句话说,你把它从一个不带参数的函数变成一个带一个或两个参数的函数,其中的参数是“下一步做什么”函数。(通常情况下,您会在一个决定两种情况的函数中使用两个参数。但对于playreach
函数,两个“下一步要做什么”步骤中的一个是“什么都不做”,因此只使用一个参数是有意义的)。这就是所谓的延续传递风格——“延续”是任何“下一步要做什么”步骤的传统函数式编程术语
下面是它的样子:
let rec PlayAgain whatToDoNext =
printfn "Do you want to play again? Please type:
1: Yes
2: No\n"
match System.Console.ReadLine() with
| "1"|"yes"|"Yes" -> printfn "Alright!!!"
whatToDoNext()
| "2"|"no"|"No" -> printfn "The game is over!"
| _ -> printfn "Invalid option! Please try again!"
(PlayAgain())
就这样!我所做的就是给playreach
一个参数,然后在适当的位置调用该参数。现在我们将main()
函数重写如下(仅更改最后一行,并使用let rec
,以便main()
函数中的名称main
可用):
let rec main()=
选择PuzzleMaker()
猜一猜
看起来你的问题只是一个简单的缩进错误。与Python一样,F#通过缩进定义代码块。让我给你举个例子:
// Some variables
let x = 5
let y = 3
let z = 1
let add1_wrong x =
printfn "Adding 1 to %d produces..." x
printfn "The wrong answer: %d" (x + 1) // Oops! This is wrong
let add1_correct x =
printfn "Adding 1 to %d produces..." x
printfn "The right answer: %d" (x + 1) // This is correct
add1_wrong x
add1_wrong y
add1_wrong z
add1_correct x
add1_correct y
add1_correct z
尝试在F#Interactive中运行该命令,您将获得以下输出:
The wrong answer: 6
Adding 1 to 5 produces...
Adding 1 to 3 produces...
Adding 1 to 1 produces...
Adding 1 to 5 produces...
The right answer: 6
Adding 1 to 3 produces...
The right answer: 4
Adding 1 to 1 produces...
The right answer: 2
注意“错误答案:6”是如何在调用add1\u错误的函数之前立即打印出来的?从代码的编写方式来看,作者似乎打算将printfn“The error answer”
行放在add1\u error
函数内,但他犯了缩进错误,将其放在函数外。因此,它与设置x
、y
和z
变量的其余代码同时运行,并调用add1\u-error
和add1\u-right
如果您还不理解示例代码中的内容,现在就停止阅读,继续阅读直到理解为止。(如果在读了两三遍之后你仍然不理解它,或者问一个后续问题,因为这意味着我没有很好地解释它)。在继续之前,请务必在我的示例代码中看到缩进错误,因为您发布的代码中也有相同的错误。实际上,您有两个缩进错误,但其中只有一个导致了您所问的问题
这是您的main()
函数,与您在本问题中键入的函数完全相同,其中有两个缩进错误:
let main() =
choosePuzzleMaker()
puzzleGuess()
c <- guess b [([],(0,0))]
while a <> c && d <> 8 do
c <- guess b [(c, validate a c)]
d <- d+1
if d <> 8 then
printfn "GZ! FUCKING MASTERMIND! You completed in %A turns and the code was %A" d a
else
printfn "That didn't go well...?"
printfn "Game Over!"
PlayAgain()
main()
rec
关键字告诉F#编译器“我定义的函数将在某个时候直接或间接地调用它自己——因此请在函数本身中使用它的名称。”关键字和
创建一组函数,这些函数的名称彼此可用
因此,解决这个问题的一种方法是执行以下操作:
let rec PlayAgain() =
// ...
and main() =
// ...
这是可行的,但我推荐第二种解决方案。函数式编程的关键思想之一是将函数视为可以操作的“东西”。也就是说,您可以将函数存储在列表或数组中