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)
一个直接的问题是您编写:
if num >=1 && <=3
Run Code Online (Sandbox Code Playgroud)
代替
if num >=1 && num <= 3
Run Code Online (Sandbox Code Playgroud)
但是即使那样,它也不起作用,因为的类型num是String(因为您使用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)
您在这里犯了一些错误,主要是与类型有关:
该行:
num <- getLine
Run Code Online (Sandbox Code Playgroud)
表示num是String,但是您以后将其用作数字。您可能要使用readLn :: Read a => IO a,并且最好也指定类型:
num <- readLn :: IO IntRun 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,所以功能。函数不是True或False。
您应该将其替换为:
if num >=1 && num <=3Run Code Online (Sandbox Code Playgroud)
稍后您写:
if num >=4 && getLine <=7Run Code Online (Sandbox Code Playgroud)
但是这里的类型再次不匹配:getLine具有类型IO String,因此它不是数字,甚至不是IO Int。您可能想重用num,因此:
if num >=4 && num <=7Run Code Online (Sandbox Code Playgroud)
最后else,您将写成:
else "Wrong health range indicated"Run Code Online (Sandbox Code Playgroud)
但是,您应该使用的类型为health而IO ()不是: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在此处使用它可以使程序更安全。
要删除第一个警告,请用空格替换选项卡。
要解决该错误,请添加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吗?您是否真的要从用户那里读取另一个号码?