Haskell,如何用 case-of 语句替换嵌套的 if?

Osc*_*nco 1 haskell

我开始学习 Haskell,我正在解决一些简单的编程挑战。所以我现在的问题只是根据传递的值打印一些文本:

main = do
  n <- readLn :: IO Int
  if n `mod` 2 > 0
      then putStrLn "Weird"
      else if n > 1 && n < 6
          then putStrLn "Not Weird"
          else if n > 5 && n < 21
              then putStrLn "Weird"
              else putStrLn "Not Weird"
Run Code Online (Sandbox Code Playgroud)

但是我认为这相当丑陋,有没有办法用更优雅的模式匹配替换嵌套的 if 结构?

我试过了:

main :: IO()
main = do
    n <- readLn :: IO Int
    case n of
        n `mod` 2 /= 0 -> putStrLn "Weird"
        n >= 2 && N <= 5 -> putStrLn "Not Weird"
        n >= 6 && N <= 20 -> putStrLn "Weird"
        n > 20 -> putStrLn "Not Weird"
Run Code Online (Sandbox Code Playgroud)

但我收到编译错误。

编辑:最终解决方案

check :: Int -> String
check n
    | (n `mod` 2 /= 0) = "Weird"
    | (n >= 2) && (n <= 5) = "Not Weird"
    | (n >= 6) && (n <= 20) = "Weird"
    | otherwise = "Not Weird"

main :: IO()
main = do
    n <- readLn :: IO Int
    putStrLn (check n)
Run Code Online (Sandbox Code Playgroud)

chi*_*chi 5

如果您有布尔表达式(条件),而不是实际模式,则需要使用守卫。

main :: IO()
main = do
    n <- readLn :: IO Int
    case () of
       _ | n `mod` 2 /= 0 -> putStrLn "Weird"
         | n >= 2 && n <= 5 -> putStrLn "Not Weird"
         | n >= 6 && n <= 20 -> putStrLn "Weird"
         | n > 20 -> putStrLn "Not Weird"
Run Code Online (Sandbox Code Playgroud)

考虑otherwise在最后一种情况下使用:假设您想捕获其他所有内容,它会更快并抑制关于非穷尽性的 GHC 警告。

“multiway if”也可以用作替代方案,但它需要扩展。