同时执行模式匹配和保护

时间:2014-07-12 02:32:33

标签: haskell

我想在一个Maybe表达式上执行模式匹配并且立即应用一个守护程序,例如:

myFunction :: Int -> Maybe Int  
myFunction x = --.................

let val = myFunction 333 
case val of
  Just val ??? if val > 0 ??? ->  "> 0 " ++ show val  
  Just val ??? if val == 0 ??? -> "== 0 " ++ show val
  Just val ??? if val < -5 and > -10??? -> "< -5 and > -10 " ++ show val
  _ -> "otherwise"

可能的?

更新

我如何&#34;链&#34; (如果可能的话)这个?我是否必须使用let

main = do
  Just val <- (lookup collection123 "value123"), val > 0 = ....
  -- or
  Just val <- (lookup collection123 "value123"), val == 0 = 
  -- or
  Just val <- (lookup collection123 "value123"), val < -5 and > -10 =
  -- or
  otherwise = --....

错误为parse error on input ,

3 个答案:

答案 0 :(得分:4)

这可以使用普通case块来完成:

case myFunction 333 of
    Just val | val > 0               ->  "> 0 " ++ show val  
             | val == 0              -> "== 0 " ++ show val
             | val < -5 && val > -10 -> "< -5 and > -10 " ++ show val
    _ -> "otherwise"

答案 1 :(得分:3)

如果我理解你的问题,你可以在定义函数时在Haskell 2010中使用pattern guards,如下所示:

myFunction m
    | Just val <- m, val > 0 = "> 0 " ++ show val
    | Just val <- m, val == 0 = "== 0 " ++ show val
    | Just val <- m, val < -5  && val > -10 = "< -5 and > -10 " ++ show val
    | otherwise = "otherwise"

模式保护为写东西提供了一种不同的(通常更简洁)风格,可以在不使用模式保护的情况下等效地完成。如果您是第二个示例,如果您仍想使用模式保护,则可以执行以下操作:

m = Just 3 -- lookup collection123 "value123"
main  
  | Just val <- m, val > 0 = do
                  putStrLn $ "> 0 " ++ show val
  | Just val <- m, val == 0 = do 
                  putStrLn $ "== 0 " ++ show val
  | Just val <- m, val < -5 && val > -10 = do
                  putStrLn $ "< -5 and > -10 " ++ show val
  | otherwise = undefined

由于main的类型为IO(),因此如果使用多个操作来处​​理每种情况,则需要使用do表示法(或以其他方式撰写)。

答案 2 :(得分:1)

您可以使用MultiWayIf来处理类似这样的语法:

{-# LANGUAGE MultiWayIf #-}
myFunction :: Int -> Maybe Int  
myFunction x = Just x

main = print $ 
  case myFunction 333 of
    Just val -> 
      if | val > 0  -> "> 0 " ++ show val  
         | val == 0 -> "== 0 " ++ show val
         | (val < -5 && val > -10) -> "< -5 and > -10 " ++ show val
         | otherwise -> "otherwise"
    _ -> "Nothing"