【问题标题】:Abstract form of "applying default value"“应用默认值”的抽象形式
【发布时间】:2014-02-04 08:50:36
【问题描述】:

我想轻松地从“失败”数据类型中取出一个值,或者在失败的情况下使用默认值。

这是我对Maybe 的实现:

infixr 1 <||>
(<||>) :: Maybe a -> a -> a
(<||>) = flip fromMaybe

pred :: String -> String -> Bool
pred x name = (x ==) <$> name `lookup` myMap <||> False

如果namemyMap 中映射到x,则pred 返回True

但正如在 Haskell 中通常的情况一样,我不知道有一种更抽象的方式来执行此操作。有人吗?

【问题讨论】:

  • maybe False (x ==) $ lookup name myMap
  • 是的,我也想过这个,但我正在寻找更多的抽象。
  • 问题在于实际上没有办法抽象出fromMaybe,因为在一般情况下,函子不允许您提取已包装的值。你总是需要一个Maybe 特定的函数,它可能是fromMaybefromJustmaybe,具体取决于你的编写方式。
  • Functor 本身无法提供这一点是有道理的,但我会想象另一个类型类可以为 Maybe、Either 等提供它。它可以为 functor 的子集实现。跨度>
  • 我想没有足够的用例让人们想要通用地这样做。一个特定的函子总是需要它,例如 Maybe

标签: haskell default default-value maybe


【解决方案1】:

这是我想出的:

class Defaultable f where
  infixr 1 <||>
  (<||>) :: f a -> a -> a

instance Defaultable Maybe where
  (<||>) = flip fromMaybe

instance Defaultable (Either a) where
  (Left _)  <||> x = x
  (Right x) <||> _ = x

Alternative 结合使用,您可以将可能的选项串在一起并在末尾添加一个默认值。

【讨论】:

    【解决方案2】:

    Foldable 可能是标准库中的合理选择:

    import Data.Foldable
    
    infixr 1 <||>
    (<||>) :: Foldable f => f a -> a -> a
    
    v <||> a =
        case toList v of
            [] -> a
            (x:xs) -> x
    

    这确实意味着您必须决定是采用找到的“第一个”元素还是“最后一个”元素。同样不幸的是,它还没有Either 实例,尽管它是coming in GHC 7.8/base 4.7。同时你可以自己定义:

    instance Foldable (Either a) where
        foldMap _ (Left _) = mempty
        foldMap f (Right y) = f y
    
        foldr _ z (Left _) = z
        foldr f z (Right y) = f y z
    

    【讨论】:

    猜你喜欢
    • 2014-07-12
    • 2018-12-19
    • 2018-08-05
    • 2017-02-11
    • 2021-01-13
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多