在 Haskell 中,是否有 <?> 运算符的抽象?
In Haskell, is there an abstraction for the <?>-operator?
我刚刚发现自己正在编写这段代码:
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
。您可以将其称为 "reverse Maybe monad",其中与 <?>
的类比是 pure
.
等价地,我可以写
Just x = mA <|> mB <|> pure c,
但我对无可辩驳的模式感到不舒服。或者,当然,
x = fromMaybe c (mA <|> mB)
因为fromMaybe === flip <?>
.
<?>
运算符的灵感来自秒差距。当我发现自己定义了这样的实用函数时,我总是很怀疑,但我在任何地方都找不到这种默认行为。
显然Alternative
和Applicative
不够强大。
我是不是错过了一个类型-class?
我能想到的 "emptyness" 仅有的两个抽象是:
首先,MonadError
:Maybe
可能有 instance MonadError () Maybe
。但是请参阅 https://github.com/ekmett/mtl/issues/27
其次,lens
_Empty
,
这是默认比较 (Eq
) 与 mempty
(of Monoid
)。然而 Monoid
和 Alternative
不同意 Maybe
.
但我不记得有任何操作员直接在上面的任何一个上工作。
我认为将事情留在 (<?>) = flip fromMaybe
是个好主意。
如果您想概括一下,Foldable
似乎是最简单的 class,带有空虚的概念:
(<?>) :: Foldable t => t a -> a -> a
ta <?> a = foldr const a ta
如果 ta
为空或 ta
的第一个元素,则此 returns a
。示例:
Just 0 <?> 10 == 0
Nothing <?> 0 == 0
[] <?> 10 == 10
实际上,我不喜欢 <?>
运算符名称作为您要查找的内容。
如果您在 Stackage or Hayoo 上搜索 Maybe a -> a -> a
类型,您可以从 errors
包中找到 ?:
运算符。
这个运算符就是所谓的 elvis-运算符。它以那种形式用在 Groovy 中。 Kotlin 也有。此运算符有助于处理命令式语言中的空值。但是,如果您认为 Maybe a
是某种可空类型,那么 ?:
运算符对您来说也很有意义。您可以观察到 ?:
运算符背后有一些历史。
此外,<?>
已经在一些包中使用,例如 megaparsec, attoparsec, optparse-generic 和其他包。而你的项目可能会使用其中一个很有可能。因此,您可能会在使用 elvis-operator.
版本时遇到一些冲突
我刚刚发现自己正在编写这段代码:
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
。您可以将其称为 "reverse Maybe monad",其中与 <?>
的类比是 pure
.
等价地,我可以写
Just x = mA <|> mB <|> pure c,
但我对无可辩驳的模式感到不舒服。或者,当然,
x = fromMaybe c (mA <|> mB)
因为fromMaybe === flip <?>
.
<?>
运算符的灵感来自秒差距。当我发现自己定义了这样的实用函数时,我总是很怀疑,但我在任何地方都找不到这种默认行为。
显然Alternative
和Applicative
不够强大。
我是不是错过了一个类型-class?
我能想到的 "emptyness" 仅有的两个抽象是:
首先,MonadError
:Maybe
可能有 instance MonadError () Maybe
。但是请参阅 https://github.com/ekmett/mtl/issues/27
其次,lens
_Empty
,
这是默认比较 (Eq
) 与 mempty
(of Monoid
)。然而 Monoid
和 Alternative
不同意 Maybe
.
但我不记得有任何操作员直接在上面的任何一个上工作。
我认为将事情留在 (<?>) = flip fromMaybe
是个好主意。
如果您想概括一下,Foldable
似乎是最简单的 class,带有空虚的概念:
(<?>) :: Foldable t => t a -> a -> a
ta <?> a = foldr const a ta
如果 ta
为空或 ta
的第一个元素,则此 returns a
。示例:
Just 0 <?> 10 == 0
Nothing <?> 0 == 0
[] <?> 10 == 10
实际上,我不喜欢 <?>
运算符名称作为您要查找的内容。
如果您在 Stackage or Hayoo 上搜索 Maybe a -> a -> a
类型,您可以从 errors
包中找到 ?:
运算符。
这个运算符就是所谓的 elvis-运算符。它以那种形式用在 Groovy 中。 Kotlin 也有。此运算符有助于处理命令式语言中的空值。但是,如果您认为 Maybe a
是某种可空类型,那么 ?:
运算符对您来说也很有意义。您可以观察到 ?:
运算符背后有一些历史。
此外,<?>
已经在一些包中使用,例如 megaparsec, attoparsec, optparse-generic 和其他包。而你的项目可能会使用其中一个很有可能。因此,您可能会在使用 elvis-operator.