首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >交互式IO的编写循环: do-notation和布局问题

交互式IO的编写循环: do-notation和布局问题
EN

Stack Overflow用户
提问于 2011-04-18 02:51:25
回答 1查看 6.8K关注 0票数 11

我刚开始使用Haskell,它完全把我搞糊涂了。我以前做过Java和Python,这对我来说更有意义。

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

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

例如:

代码语言:javascript
复制
Continue? y/n:
> assd
Invalid input.
Continue? y/n:
> y
(something happens)
Continue? y/n:
> n
(Close program)

以farmiliar格式编写它,一个类似如下的函数:

代码语言:javascript
复制
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 (实际上是今天),我不知道我能做什么,不能做什么。我在想一些类似的东西:

代码语言:javascript
复制
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论坛?我找不到任何=/)

EN

回答 1

Stack Overflow用户

发布于 2011-04-18 03:09:17

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

我已经将提示字符串变成了一个参数,所以您可以使用该函数来提出各种yes/no问题:

代码语言:javascript
复制
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

然后,您可以从交互循环中调用您的函数:

代码语言:javascript
复制
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 ()
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5695649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档