我刚刚发现自己编写了这段代码:
import Control.Applicative ((<|>))
x = mA <|> mB <?> c
(<?>) :: Maybe a -> a -> a
Just x <?> _ = x
Nothing <?> y = y
mA :: Maybe a
,mB :: Maybe a
,c :: a
和x :: a
。基本上,代码说:选择不是empty
的第一个替代品,默认为c
。您可以将其称为“反向可能monad”,其中与<?>
的类比为pure
。
同样,我可以写
Just x = mA <|> mB <|> pure c,
但我对无可辩驳的模式感到不舒服。或者,当然,
x = fromMaybe c (mA <|> mB)
因为fromMaybe === flip <?>
。
<?>
运算符的灵感来自parsec。当我发现自己定义这样的效用函数时,我总是怀疑,但我无法在任何地方找到这种默认行为。
显然Alternative
和Applicative
不够强大。
我是否错过了一个类型?
答案 0 :(得分:8)
我认为把事情留在(<?>) = flip fromMaybe
是个好主意。
如果你想概括一下,Foldable
似乎是最简单的类,有一个空虚的概念:
(<?>) :: Foldable t => t a -> a -> a
ta <?> a = foldr const a ta
如果a
为空,则返回ta
,否则返回ta
的第一个元素。例子:
Just 0 <?> 10 == 0
Nothing <?> 0 == 0
[] <?> 10 == 10
答案 1 :(得分:3)
我能想到的唯一两个“空虚”的抽象是:
首先,MonadError
:Maybe
可能有instance MonadError () Maybe
。但请参见https://github.com/ekmett/mtl/issues/27
其次,lens
_Empty
,
默认情况下,Eq
与mempty
(Monoid
)进行比较(Monoid
)。但Alternative
和Maybe
不同意if (!empty($value['course_name']))
{
// do somthing
}
else
{
//do something
}
。
但我不记得有任何操作员直接在上面的任何一个工作。
答案 2 :(得分:3)
实际上,我不喜欢<?>
运营商名称,因为您正在寻找什么。
如果您在Stackage或Hayoo上搜索Maybe a -> a -> a
类型,则可以从?:
包中找到errors
运算符。
这个操作符叫做 elvis -operator。它以Groovy的形式使用。 Kotlin也有它。此运算符有助于处理命令式语言中的空值。但如果您认为Maybe a
是某种可空类型,那么?:
运算符对您来说也是有意义的。您可以观察到?:
运算符背后有一些历史记录。
此外,<?>
已用于某些软件包,例如megaparsec,attoparsec,optparse-generic等。您的项目可能会使用其中一个概率很高的项目。因此,使用您的 elvis -operator。