【问题标题】:How to use Data.Map.lookup in the context of an Either monad?如何在 Either monad 的上下文中使用 Data.Map.lookup?
【发布时间】:2013-11-11 05:01:10
【问题描述】:

我正在尝试使用 Data.Map 将字符串映射到函数。我遇到的问题是我的程序中的主要错误处理使用了 Either monad,Map.lookup 将返回Maybe ([SomeVal] -> Either ValError SomeVal)。在这种情况下,如何让 Map.lookup 与 Either monad 很好地配合?

apply :: String -> [SomeVal] -> Either ValError SomeVal
apply s args = (Map.lookup s prims) >>= \fn -> fn args

prims :: Map String ([SomeVal] -> Either ValError SomeVal)
prims = Map.fromList
    [("key", function)
    ,("key2", function2)
    ]

::> apply "key" [val1, val2, val3]

【问题讨论】:

    标签: haskell maybe either


    【解决方案1】:

    Control.Error package 有一个不错的功能

    note :: e -> Maybe a -> Either e a
    note e Nothing  = Left e
    note _ (Just a) = Right a
    

    这对于将类似Maybe 的故障“升级”为类似Either 的故障很有用。

    lookupNote :: k -> Map.Map k v -> Either ValError v
    lookupNote k = note (Missing k) . lookup k
    

    它还有许多其他类似的方法,用于在 EitherMaybe 的转换器和通用 MonadPlus 实例之间进行映射。我强烈推荐这个包。

    【讨论】:

    • 我认为这在将来会非常有用,但我认为 Map.findWithDefault 是处理这个问题的最干净的方法。
    【解决方案2】:

    其他答案已经解释了如何将Maybe 转换为Either。但是对于Data.Map,您可以使用Map.findWithDefault,而不是Map.lookup,它不会包含在Maybe 中,并允许您选择如何处理不存在的密钥。

    【讨论】:

      【解决方案3】:

      这取决于您要如何处理Nothing 案例。如果你想断言钥匙永远在那里(一个坏主意)

      import Data.Maybe
      apply s args = (prims ! s) args
      

      但更聪明的方法是在没有发现任何东西的情况下拥有一个理智的值。您可能需要一些 ValError 构造函数

      ValError = ...
               | NoKey String
               ...
      apply s args = maybe (Left $ NoKey s) ($args) $ M.lookup s prims
      

      或者只想保留Maybe

      apply :: String -> [SomeVal] -> Maybe (Either ValError SomeVal)
      

      在没有找到密钥的情况下,这些方法中的任何一种都提供了更明智的语义。您选择的主要是偏好,如果您打算使 apply 成为您 API 的一个非常基本的部分,以至于 ValErrors 应该知道它,那么 1 效果很好。

      否则,2 使用起来会更痛苦,但不需要更改任何令人愉快的现有代码。

      【讨论】:

      • 我喜欢这里的第二种情况:也许是一个棘手的小功能......很高兴我现在知道了。
      猜你喜欢
      • 2021-09-04
      • 1970-01-01
      • 2012-06-02
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 2016-07-31
      相关资源
      最近更新 更多