首页 > 解决方案 > Haskell,如何用 case-of 语句替换嵌套的 if?

问题描述

我开始学习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"

但是我认为这相当难看,有没有办法可以用更优雅的模式匹配替换嵌套的 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"

但我得到一个编译错误。

编辑:最终解决方案

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)

标签: haskell

解决方案


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

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"

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

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


推荐阅读