我刚开始使用Haskell,它完全把我搞糊涂了。我以前做过Java和Python,这对我来说更有意义。
我目前正在尝试获取一个用户输入,检查它是否有效,如果不是:打印一个错误并再次获取输入;如果有效:从它产生一个布尔值。
更准确地说,我需要一个yes/no输入,其中'y‘将生成True,'n’将生成False,任何其他输入将在命令行中打印一条消息,并要求再次输入y/n。
例如:
Continue? y/n:
> assd
Invalid input.
Continue? y/n:
> y
(something happens)
Continue? y/n:
> n
(Close program)以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
)
)由于许多原因,这并不起作用。我的主要问题是我不知道这个"do“是做什么的。我刚刚读到它是在需要io操作时使用的,并以某种方式执行了以下表达式。在haskell中,所有的东西都被赋值,这对我来说是没有意义的。“做”的评估结果是什么?另外,需要什么样的缩进?它似乎是一种随机的。我知道函数必须计算出我的布尔值,这在使用"do“操作时似乎是不可能的。但是,如何在将某些内容打印到控制台的同时仍然使其成为计算结果为True或False的表达式的一部分呢?
谢谢你的帮助。
(顺便说一下。互联网上有没有活跃的haskell论坛?我找不到任何=/)
发布于 2011-04-18 03:09:17
由于您的函数需要执行IO,因此它必须在IO monad中返回一个值,因此它的类型需要为yesno :: IO Bool,并且True和False值需要由return提升到monad中。您还需要getLine而不是readLn,因为您需要的是原始字符串,而不是已解析的值(这可能会导致解析错误)。最后,您需要在调用getLine之前执行hFlush stdout,否则提示符仍将位于缓冲区中等待换行(这需要您导入System.IO)。
我已经将提示字符串变成了一个参数,所以您可以使用该函数来提出各种yes/no问题:
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然后,您可以从交互循环中调用您的函数:
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 ()https://stackoverflow.com/questions/5695649
复制相似问题