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

Haskell: Multi-way if-expressions need MultiWayIf turned on

正在尝试使用 "stack build" 构建:

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

嗯,在 Haskell 中只有一个 if-then-else 子句。如果你想要这些“multi-if”语句,你可以使用 guard.

使用守卫

你的语法已经很接近守卫了,只是它 not 有一个 if 关键字,并且等号 (=) 用于表示这种情况下的输出。

所以你应该将其重写为:

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

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

使用模式s

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

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

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

使用 MultiWayIf 扩展程序

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

<b>{-# LANGUAGE MultiWayIf #-}</b>

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 <b>-XMultiWayIf</b>
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| :}