gpt4 book ai didi

Haskell - 守卫内部案件陈述

转载 作者:行者123 更新时间:2023-12-03 01:39:23 25 4
gpt4 key购买 nike

我正在经历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 block 转换为这样的保护语句:

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 中 guard 的使用非常严格/不直观。 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

我认为明确的引用是 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

关于Haskell - 守卫内部案件陈述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40836222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com