通过比较用户输入的数值来打印健康状态

Ema*_*uel 1 io conditional haskell getline

我正在尝试从用户那里获得一个数值(范围为1-10),并使用条件语句(if number >= 1 && <=3)打印出健康状态(例如putStrLn "your health is poor"),但是却收到了我无法通过的错误消息

health :: IO ()
health = do 
        putStrLn "State your health using numbers 1 - 10: "
        num <- getLine
        --putStrLn "Your health is: "
        if num >=1 && <=3
              then 
               do putStrLn "Your health is poor"
           else if num >=4 && getLine <=7
              then putStrLn "Your health is OK"
           else if num >=8 && getLine<=10
              then putStrLn "your health is fanstastic"
              else "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

错误信息:

healthCheck.hs:9:1: warning: [-Wtabs]
Tab character found here, and in five further locations.
Please use spaces instead.
|
9 |                         --putStrLn "Your health is: "   | ^^^^^^^^

healthCheck.hs:10:39: error: parse error on input ‘<=’
|
10 |                         if num >=1 && <=3    |
Run Code Online (Sandbox Code Playgroud)

Ale*_*aga 8

一个直接的问题是您编写:

if num >=1 && <=3
Run Code Online (Sandbox Code Playgroud)

代替

if num >=1 && num <= 3
Run Code Online (Sandbox Code Playgroud)

但是即使那样,它也不起作用,因为的类型numString(因为您使用getLine :: IO String,并且您无法将其与数值进行比较。

您将需要使用类似于read将字符串“读取”为数字值的方法(请注意,如果字符串不代表数字值,它将崩溃)。

接下来,getLine <= 7由于同样的原因:,表达式like 也将不起作用:getLine :: IO String因此,您无法IO String与数字值进行比较。

该代码将起作用:

health :: IO ()
health = do
            putStrLn "State your health using numbers 1 - 10: "
            str <- getLine
            let num = read str
            --putStrLn "Your health is: "
            if (num >=1 && num <=3 )
               then putStrLn "Your health is poor"
               else if num >=4 && num <=7
                  then putStrLn "Your health is OK"
               else if num >=8 && num <=10
                  then putStrLn "your health is fanstastic"
                  else putStrLn "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

但是,我建议您查看case表达式或/,MultiWayIf因为这可能是编写此代码的更好方法:

health :: IO ()
health = do
  putStrLn "State your health using numbers 1 - 10: "
  str <- getLine
  case read str of
    num | num >= 1 && num <= 3 -> putStrLn "Your health is poor"
    num | num >= 4 && num <= 7 -> putStrLn "Your health is OK"
    num | num >= 8 && num <=10 -> putStrLn "your health is fanstastic"
    _ -> putStrLn "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

  • 将`readLn`优先于`getLine` +`read`:当无法解析输入时,它会做正确的事,但有例外。在这种特殊情况下,这并不重要,但这是一个养成的好习惯。 (3认同)

Wil*_*sem 6

您在这里犯了一些错误,主要是与类型有关:

该行:

num <- getLine
Run Code Online (Sandbox Code Playgroud)

表示numString,但是您以后将其用作数字。您可能要使用readLn :: Read a => IO a,并且最好也指定类型:

num <- readLn :: IO Int
Run Code Online (Sandbox Code Playgroud)

在您的第一种if情况下:

if num >=1 && <=3
Run Code Online (Sandbox Code Playgroud)

由于将其解析为是错误的(num >= 1) && (<= 3)。正确的操作因而不是一个Bool,而是一个(Num n, Ord n) => n -> Bool,所以功能。函数不是TrueFalse

您应该将其替换为:

if num >=1 && num <=3
Run Code Online (Sandbox Code Playgroud)

稍后您写:

if num >=4 && getLine <=7
Run Code Online (Sandbox Code Playgroud)

但是这里的类型再次不匹配:getLine具有类型IO String,因此它不是数字,甚至不是IO Int。您可能想重用num,因此:

if num >=4 && num <=7
Run Code Online (Sandbox Code Playgroud)

最后else,您将写成:

else "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

但是,您应该使用的类型为healthIO ()不是:StringputStrLn

else putStrLn "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

您可以将putStrLn其分解为:

health :: IO ()
health = do 
    putStrLn "State your health using numbers 1 - 10: "
    num <- readLn :: IO Int
    --putStrLn "Your health is: "
    putStrLn $
        if num <= 0 || num > 10 then "Wrong health range indicated"
        else if num <= 3 then "Your health is poor"
        else if num <= 7 then "Your health is OK"
        else "your health is fanstastic"
Run Code Online (Sandbox Code Playgroud)

上面的方法仍然不理想,因为将字符串读入Int可能会出错。因此,readMaybe在此处使用它可以使程序更安全。


chi*_*chi 5

要删除第一个警告,请用空格替换选项卡。

要解决该错误,请添加num<=3

if num >=1 && num <=3
Run Code Online (Sandbox Code Playgroud)

您还需要在putStrLn此处添加一个:

else putStrLn "Wrong health range indicated"
Run Code Online (Sandbox Code Playgroud)

另外,您不能在中使用getLineas getLine <= 7。不应该这样num吗?您是否真的要从用户那里读取另一个号码?