Haskell:多路if表达式需要启用MultiWayIf

Diy*_*aev 1 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)
Run Code Online (Sandbox Code Playgroud)

我得到了:

    Multi-way if-expressions need MultiWayIf turned on
  |
6 |   if | standard == 999 -> "Wow! 999 standard!"
  |   ^^
Run Code Online (Sandbox Code Playgroud)

怎么解决?

堆栈1.7.1,GHC 8.2.2

Wil*_*sem 10

好在Haskell中只有一个if- then- else子句.如果你想要这些" multi-if "语句,你可以使用一个警卫.

使用警卫

你的语法已经相当接近保护,但它并不能有一个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..."
Run Code Online (Sandbox Code Playgroud)

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

使用模式小号

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

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..."
Run Code Online (Sandbox Code Playgroud)

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

使用MultiWayIf扩展名

您还可以启用GHCi扩展来启用此扩展,方法是在文件头部编写pragma,或者-XMultiWayIf在调用解释器时使用.所以:

{-# 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..."
Run Code Online (Sandbox Code Playgroud)

要么:

$ 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| :}
Run Code Online (Sandbox Code Playgroud)

  • 正如错误消息所示,在启用`-XMultiWayIf`时,他的文件正常工作(不需要编辑). (2认同)
  • 我相信 `-X` 标志应该只用于 GHCi。当编译一个合适的模块时,你应该使用 `LANGUAGE` pragmas 或*可能*`.cabal` 文件中的 `default-extensions` 字段。当您的包使用大量扩展并在任何地方使用它们时,后者很有用,但它使读者更难看到模块中正在运行的扩展。 (2认同)