Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/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
Loops 为交互式IO编写循环:do符号和布局的问题_Loops_Haskell_Io - Fatal编程技术网

Loops 为交互式IO编写循环:do符号和布局的问题

Loops 为交互式IO编写循环:do符号和布局的问题,loops,haskell,io,Loops,Haskell,Io,我刚刚开始Haskell,这让我完全困惑。我以前做过Java和Python,这对我来说更有意义 我目前正在尝试获取用户输入,检查它是否有效,如果无效:打印错误并再次获取输入;如果有效:从中生成布尔值 更准确地说,我需要一个yes/no输入,其中“y”将生成True,“n”将生成False,任何其他输入都将在命令行中打印一条消息,并要求再次输入y/n 例如: 以farmiliar格式编写,函数如下: boolean inputBool() { while(True) { st

我刚刚开始Haskell,这让我完全困惑。我以前做过Java和Python,这对我来说更有意义

我目前正在尝试获取用户输入,检查它是否有效,如果无效:打印错误并再次获取输入;如果有效:从中生成布尔值

更准确地说,我需要一个yes/no输入,其中“y”将生成True,“n”将生成False,任何其他输入都将在命令行中打印一条消息,并要求再次输入y/n

例如:

以farmiliar格式编写,函数如下:

boolean inputBool() {
    while(True) {
       str = input("Continue? y/n: ");
       if (str == "y") {
           return True;
       } else if (str == "n") {
           return False;
       } else {
           print("Invalid input");
       }
}

--main program--

while(inputBool()) {
    doSomething();
}
因为我刚刚开始haskell(实际上是今天),我不知道我能做什么或不能做什么。 我在想类似的事情:

yesno :: Bool
yesno = do
        putStr "Continue? y/n: " 
        str <- readLn
        if (str == "y") then True else (
            if (str == "n") then False else (
                do
                putStrLn "Invalid input."
                yesno
            )    
        )
yesno::Bool
是的
putStr“是否继续?是/否:”

str由于函数需要执行IO,它必须在
IO
monad中返回一个值,因此它的类型必须是
yesno::IO Bool
,并且
True
False
值需要通过
return
提升到monad中。您还需要
getLine
而不是
readLn
,因为您需要的是原始字符串,而不是解析后的值(这可能会导致解析错误)。最后,在调用
getLine
之前,您需要
hFlush stdout
,否则提示符仍将位于缓冲区中等待换行(这要求您导入System.IO)

我已将提示字符串设置为参数,因此您可以使用该函数询问各种是/否问题:

import System.IO

yesno :: String -> IO Bool
yesno prompt = do
          putStr $ prompt ++ " y/n: "
          hFlush stdout
          str <- getLine
          case str of
            "y" -> return True
            "n" -> return False
            _   -> do
              putStrLn "Invalid input."
              yesno prompt
import System.IO
是否::字符串->IO布尔
yesno prompt=do
PUTSR$prompt++“是/否:”
hFlush stdout
str返回True
“n”->返回False
_->做
putStrLn“无效输入。”
是的,没有提示
然后,您可以从交互循环调用您的函数:

main :: IO ()
main = do
         fun <- yesno "Is Haskell fun?"
         if fun
          then putStrLn "rock on"
          else putStrLn "read more tutorials"
         continue <- yesno "Continue?"
         if continue then main else return ()
main::IO()
main=do

有趣的可能从一个好的教程开始:或者Haskell讨论的最佳论坛是Haskell Reddit,Haskell Stackoverflow标签;哈斯克尔IRC频道;或者haskell cafe@maillist。事实上,我真的受够了教程和那些冗长的解释。自从我开始编程以来,我所需要的只是语法、关键字、一份好的文档和一点实践。通过这篇文章,Java在几天内就学会了,python很容易,因为我已经了解Java。如果语言的语义与您已经知道的不同,语法和关键字对您没有帮助,就像Haskell一样。你需要一个好的教程。事实上,我向你推荐哈斯克尔-beginners@haskell.org而不是haskell-cafe@haskell.org,唐在上面提到过。非常感谢。我想我理解了这一点,所以“do”的计算结果是它的最后一个表达式?基本上。“do”块将根据执行路径计算为
返回产生的值。是的,do是“语法糖”,它将一系列作为语句的表达式粘合到一个大表达式中。glue操作符(>>=)又称为
bind
@Maro,假设在到达之前没有错误或失败或其他“提前退出”,是的。您必须注意
返回
。它与Java或Python中的return不同。在Haskell中,
return
将值包装在一元外壳中,生成一元值。它不会导致
do
块停止执行。通常,您将在
do
块中看到
return
作为叶表达式,因此它将是从该块返回的值。
main :: IO ()
main = do
         fun <- yesno "Is Haskell fun?"
         if fun
          then putStrLn "rock on"
          else putStrLn "read more tutorials"
         continue <- yesno "Continue?"
         if continue then main else return ()