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