簡體   English   中英

Haskell - 守衛案件陳述

[英]Haskell - guard inside case statement

我正在通過了解你是一本哈斯克書,在第8章中有一段代碼看起來像這樣

data LockerState = Taken | Free deriving (Eq, Show)
type Code = String
type LockerMap = Map.Map Int (LockerState, Code)

lookup' :: Int -> LockerMap -> Either String Code
lookup' num_ map_ =
   case (Map.lookup num_ map_) of
      Nothing -> Left $ "LockerNumber doesn't exist!"
      Just (state, code) -> if state == Taken
                              then Left $ "LockerNumber already taken!"
                              else Right $ code

這有效。 但是,我想將if / else塊轉換為保護語句,如下所示:

lookup' :: Int -> LockerMap -> Either String Code
lookup' num_ map_ =
   case (Map.lookup num_ map_) of
      Nothing -> Left $ "LockerNumber doesn't exist!"
      Just (state, code) ->
         | state == Taken = Left $ "LockerNumber already taken!"
         | otherwise = Right $ Code

這不編譯。 似乎在Haskell中使用防護是非常嚴格/非直觀的。 SO Ex1 SO Ex2 是否有一個明確的來源,我可以閱讀,告訴我哪些地方我可以使用警衛?

允許使用兩個防護:功能定義和case表達。 在這兩種情況下,守衛出現一個模式之后和身體之前 ,所以你在函數中使用=-> case分支,像往常一樣:

divide x y
  | y == 0 = Nothing
  --------
  | otherwise = Just (x / y)
  -----------

positively mx = case mx of
  Just x | x > 0 -> Just x
         -------
  _ -> Nothing

防護只是模式的約束 ,所以Just x匹配任何非Nothing值,但Just x | x > 0 Just x | x > 0僅匹配其包裝值也為正的Just

我認為最終的引用是Haskell報告 ,特別是§3.13案例表達式和§4.4.3函數和模式綁定,它們描述了守衛的語法並指定了它們被允許的位置。

在您的代碼中,您需要:

Just (state, code)
  | state == Taken -> Left "LockerNumber already taken!"
  | otherwise -> Right code

僅使用模式也可以表達這一點:

Just (Taken, _) -> Left "LockerNumber already taken!"
Just (_, code) -> Right code

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM