Haskell - case 语句中的守卫
Haskell - guard inside case statement
我正在阅读 Learn you a haskell 这本书,在第 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 块转换为 guard 语句,如下所示:
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 中守卫的使用似乎非常 restrictive/non 直观。 SO Ex2。是否有我可以阅读的明确来源告诉我可以在哪些地方使用警卫?
有两个地方允许使用守卫:函数定义和 case
表达式。在这两种情况下,守卫出现在 after 模式和 before the body,所以你在函数中使用 =
和 ->
在 case
个分支中,像往常一样:
divide x y
| y == 0 = Nothing
--------
| otherwise = Just (x / y)
-----------
positively mx = case mx of
Just x | x > 0 -> Just x
-------
_ -> Nothing
Guards 只是 constraints 模式,所以 Just x
匹配任何非 Nothing
值,但 Just x | x > 0
只匹配 Just
which wrapped value 也是正数。
我想权威参考是 Haskell Report,特别是 §3.13 Case Expressions 和 §4.4.3 Function and Pattern Bindings,它们描述了守卫的语法并指定了它们的允许位置。
在您的代码中,您需要:
Just (state, code)
| state == Taken -> Left "LockerNumber already taken!"
| otherwise -> Right code
这也可以单独用模式来表达:
Just (Taken, _) -> Left "LockerNumber already taken!"
Just (_, code) -> Right code
我正在阅读 Learn you a haskell 这本书,在第 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 块转换为 guard 语句,如下所示:
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 中守卫的使用似乎非常 restrictive/non 直观。
有两个地方允许使用守卫:函数定义和 case
表达式。在这两种情况下,守卫出现在 after 模式和 before the body,所以你在函数中使用 =
和 ->
在 case
个分支中,像往常一样:
divide x y
| y == 0 = Nothing
--------
| otherwise = Just (x / y)
-----------
positively mx = case mx of
Just x | x > 0 -> Just x
-------
_ -> Nothing
Guards 只是 constraints 模式,所以 Just x
匹配任何非 Nothing
值,但 Just x | x > 0
只匹配 Just
which wrapped value 也是正数。
我想权威参考是 Haskell Report,特别是 §3.13 Case Expressions 和 §4.4.3 Function and Pattern Bindings,它们描述了守卫的语法并指定了它们的允许位置。
在您的代码中,您需要:
Just (state, code)
| state == Taken -> Left "LockerNumber already taken!"
| otherwise -> Right code
这也可以单独用模式来表达:
Just (Taken, _) -> Left "LockerNumber already taken!"
Just (_, code) -> Right code