Haskell:多路if表达式需要打开MultiWayIf

时间:2018-06-10 21:32:50

标签: haskell ghc

尝试使用"堆栈构建":

进行构建
module Main where


analyzeGold :: Int -> String
analyzeGold standard =
  if | standard == 999 -> "Wow! 999 standard!"
     | standard == 750 -> "Great! 750 standard."
     | standard == 585 -> "Not bad! 585 standard."
     | otherwise -> "I don't know such a standard..."

main :: IO ()
main = do
  putStrLn (analyzeGold 999)

我得到了:

    Multi-way if-expressions need MultiWayIf turned on
  |
6 |   if | standard == 999 -> "Wow! 999 standard!"
  |   ^^

如何解决?

堆栈1.7.1,GHC 8.2.2

1 个答案:

答案 0 :(得分:10)

在Haskell中,只有if - then - else子句。如果您需要这些“ multi-if ”语句,则使用 guard

使用警卫

你的语法已经非常接近一个守卫,除了它有一个 if 关键字,并且等号( = )用于表示该情况下的输出。

所以你应该把它重写为:

analyzeGold :: Int -> String
analyzeGold standard
    | standard == 999 = "Wow! 999 standard!"
    | standard == 750 = "Great! 750 standard."
    | standard == 585 = "Not bad! 585 standard."
    | otherwise = "I don't know such a standard..."

有关警卫语法和使用的一些信息,请参阅here [lyah]

使用模式 s

由于每次检查都检查整数文字的相等性,我们实际上可以将检查从守卫移到模式,如:

analyzeGold :: Int -> String
analyzeGold 999 = "Wow! 999 standard!"
analyzeGold 750 = "Great! 750 standard."
analyzeGold 585 = "Not bad! 585 standard."
analyzeGold _ = "I don't know such a standard..."

这里下划线(_)充当通配符,匹配所有值(以及所有未与前面的子句匹配的模式)。

使用MultiWayIf扩展名

您还可以通过在文件头部编写pragma或在调用解释器时使用-XMultiWayIf来启用GHCi扩展来启用此扩展。所以:

{-# LANGUAGE MultiWayIf #-}

analyzeGold :: Int -> String
analyzeGold standard =
    if | standard == 999 -> "Wow! 999 standard!"
       | standard == 750 -> "Great! 750 standard."
       | standard == 585 -> "Not bad! 585 standard."
       | otherwise -> "I don't know such a standard..."

或者:

$ ghci -XMultiWayIf
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Prelude> :{
Prelude| analyzeGold :: Int -> String
Prelude| analyzeGold standard =
Prelude|     if | standard == 999 -> "Wow! 999 standard!"
Prelude|        | standard == 750 -> "Great! 750 standard."
Prelude|        | standard == 585 -> "Not bad! 585 standard."
Prelude|        | otherwise -> "I don't know such a standard..."
Prelude| :}