Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何要求用户在控制台F中再次播放#_F# - Fatal编程技术网

F# 如何要求用户在控制台F中再次播放#

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 <

好的,我现在正在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 <> 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() =
    // ...
这是可行的,但我推荐第二种解决方案。函数式编程的关键思想之一是将函数视为可以操作的“东西”。也就是说,您可以将函数存储在列表或数组中