编写此代码的更短方法

发布于 2024-12-05 08:17:32 字数 99 浏览 4 评论 0 原文

以下模式在 Haskell 代码中经常出现。有没有更短的写法?

if pred x
then Just x
else Nothing

The following pattern appears very frequently in Haskell code. Is there a shorter way to write it?

if pred x
then Just x
else Nothing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

晨光如昨 2024-12-12 08:17:32

您正在寻找 Control.Monad 中的 >mfilter:

mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

-- mfilter odd (Just 1) == Just 1
-- mfilter odd (Just 2) == Nothing

请注意,如果条件不依赖于 MonadPlus 的内容,您可以改为编写:

"foo" <$ guard (odd 3) -- Just "foo"
"foo" <$ guard (odd 4) -- Nothing

You're looking for mfilter in Control.Monad:

mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

-- mfilter odd (Just 1) == Just 1
-- mfilter odd (Just 2) == Nothing

Note that if the condition doesn't depend on the content of the MonadPlus, you can write instead:

"foo" <$ guard (odd 3) -- Just "foo"
"foo" <$ guard (odd 4) -- Nothing
赢得她心 2024-12-12 08:17:32

嗯...您正在寻找一个带有 a 的组合器,一个函数 a ->; Bool 并返回一个Maybe a。停止! 胡格尔时间。没有完全匹配,但 find 非常接近:

find :: (a -> Bool) -> [a] -> Maybe a

我怀疑您是否真的可以在某处找到您的函数。但为什么不自己定义呢?

ifMaybe :: (a -> Bool) -> a -> Maybe a
ifMaybe f a | f a = Just a
ifMaybe _ _       = Nothing

Hm... You are looking for a combinator that takes an a, a function a -> Bool and returns a Maybe a. Stop! Hoogle time. There is no complete match, but find is quite close:

find :: (a -> Bool) -> [a] -> Maybe a

I doubt that you can actually find your function somewhere. But why not define it by yourself?

ifMaybe :: (a -> Bool) -> a -> Maybe a
ifMaybe f a | f a = Just a
ifMaybe _ _       = Nothing
那小子欠揍 2024-12-12 08:17:32

您可以使用 guard 来实现此行为:

guard (pred x) >> return x

这是一种非常有用的行为,我什至在我自己的一小套代码中一次性定义了 ensure (每个人有这样的事情,对吗?

ensure p x = guard (p x) >> return x

You can use guard to achieve this behavior:

guard (pred x) >> return x

This is such a generally useful behavior that I've even defined ensure in my own little suite of code for one-offs (everybody has such a thing, right? ;-):

ensure p x = guard (p x) >> return x
沙沙粒小 2024-12-12 08:17:32

使用:

(?:) (5>2) (Just 5,Nothing)

来自 Data.Bool.HT。

Use:

(?:) (5>2) (Just 5,Nothing)

from Data.Bool.HT.

柠檬 2024-12-12 08:17:32
f pred x = if pred x then Just x else Nothing

有了上面的定义,你可以简单地写:

f pred x

当然,这与 Daniel Wagner 的 ensure 或 FUZxxl 的 ifMaybe 没有什么不同。但它的名称很简单 f,使其成为最短的,并且它的定义正是您给出的代码,使其成为最容易证明正确的代码。 ;)

一些 ghci,只是为了好玩

ghci> let f pred x = if pred x then Just x else Nothing
ghci> f (5>) 2
Just 2
ghci> f (5>) 6
Nothing

如果你不能告诉,这不是一个非常严肃的答案。其他人更有洞察力,但我无法抗拒半开玩笑的回应“让这段代码更短”。

f pred x = if pred x then Just x else Nothing

Given the above definition, you can simply write:

f pred x

Of course this is no different than Daniel Wagner's ensure or FUZxxl's ifMaybe. But it's name is simply f, making it the shortest, and it's definition is precisely the code you gave, making it the most easily proven correct. ;)

Some ghci, just for fun

ghci> let f pred x = if pred x then Just x else Nothing
ghci> f (5>) 2
Just 2
ghci> f (5>) 6
Nothing

If you couldn't tell, this isn't a very serious answer. The others are a bit more insightful, but I couldn't resist the tongue-in-cheek response to "make this code shorter".

梦里泪两行 2024-12-12 08:17:32

通常我是非常通用的代码的忠实粉丝,但实际上我发现这个确切的函数非常有用,专门用于Maybe,我保留它而不是使用guardmfilter 等。

我使用的名称是 justIf,我通常使用它来执行以下操作:

∀x. x ⊢ import Data.List
∀x. x ⊢ unfoldr (justIf (not . null . snd) . splitAt 3) [1..11]
[[1,2,3],[4,5,6],[7,8,9]]

基本上,需要在复合表达式中完成某种按元素过滤或检查的内容,所以用Maybe来表示谓词的结果。

对于像这样的专门版本,您实际上无法做太多事情来缩短它。这已经很简单了。简洁和只是为了字符数而敲代码之间有一条微妙的界限,对于这么简单的事情,我真的不会担心尝试“改进”它......

Usually I'm a big fan of very generic code, but I actually find this exact function useful often enough, specialized to Maybe, that I keep it around instead of using guard, mfilter, and the like.

The name I use for it is justIf, and I'd typically use it for doing things like this:

∀x. x ⊢ import Data.List
∀x. x ⊢ unfoldr (justIf (not . null . snd) . splitAt 3) [1..11]
[[1,2,3],[4,5,6],[7,8,9]]

Basically, stuff where some sort of element-wise filtering or checking needs to be done in a compound expression, so Maybe is used to indicate the result of the predicate.

For the specialized version like this, there really isn't much you can do to make it shorter. It's already pretty simple. There's a fine line between being concise, and just golfing your code for character count, and for something this simple I wouldn't really worry about trying to "improve" it...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文