首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell,如何用case语句替换嵌套的if?

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

Stack Overflow用户
提问于 2019-12-15 19:07:51
回答 3查看 365关注 0票数 2

我开始学习haskell,我正在解决一些简单的编程挑战。因此,我目前的问题是根据传递的值打印一些文本:

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

我试过:

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

但是我得到了一个编译错误。

编辑:最终解决方案

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

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-15 19:15:23

[Haskell-report]处理模式。像n `mod` 2 /= 0这样的表达式不是一个模式。

我建议定义一个助手函数,并使用保护程序。

代码语言:javascript
复制
tmp :: Int -> String
tmp n | n `mod` 2 /= 0 = "Weird"
      | n >= 2 && N <= 5 = "Not Weird"
      | n >= 6 && N <= 20 = "Weird"
      | n > 20 = "Not Weird"
      | otherwise = …

您仍然需要为otherwise案例定义一个值,以防n <= 0

然后,我们可以将其与以下内容结合使用:

代码语言:javascript
复制
main = do
    n <- readLn
    putStrLn (tmp n)
票数 3
EN

Stack Overflow用户

发布于 2019-12-15 19:12:41

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

代码语言:javascript
复制
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“也可以用作替代方法,但它需要扩展。

票数 5
EN

Stack Overflow用户

发布于 2019-12-16 07:31:14

“多路如果”在chi的回答中提到,但没有解释,我认为了解这种情况是有用的。启用the MultiWayIf extension (例如在文件顶部写入{-# LANGUAGE MultiWayIf #-} )允许您编写

代码语言:javascript
复制
if | (n `mod` 2 /= 0) -> putStrLn "Weird"
   | (n >= 2) && (n <= 5) -> putStrLn "Not Weird"
   | (n >= 6) && (n <= 20) -> putStrLn "Weird"
   | otherwise -> putStrLn "Not Weird"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59347208

复制
相关文章

相似问题

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