我开始学习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)发布于 2019-12-15 19:15:23
[Haskell-report]处理模式。像n `mod` 2 /= 0这样的表达式不是一个模式。
我建议定义一个助手函数,并使用保护程序。
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。
然后,我们可以将其与以下内容结合使用:
main = do
n <- readLn
putStrLn (tmp n)发布于 2019-12-15 19:12:41
如果您有布尔表达式(条件),而不是实际的模式,则需要使用保护。
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“也可以用作替代方法,但它需要扩展。
发布于 2019-12-16 07:31:14
“多路如果”在chi的回答中提到,但没有解释,我认为了解这种情况是有用的。启用the MultiWayIf extension (例如在文件顶部写入{-# LANGUAGE MultiWayIf #-} )允许您编写
if | (n `mod` 2 /= 0) -> putStrLn "Weird"
| (n >= 2) && (n <= 5) -> putStrLn "Not Weird"
| (n >= 6) && (n <= 20) -> putStrLn "Weird"
| otherwise -> putStrLn "Not Weird"https://stackoverflow.com/questions/59347208
复制相似问题