编写此代码的方法较短

use*_*101 16 haskell if-statement combinators maybe

Haskell代码中经常出现以下模式.是否有更短的方式来写它?

if pred x
then Just x
else Nothing
Run Code Online (Sandbox Code Playgroud)

Lan*_*dei 28

您正在寻找mfilterControl.Monad:

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

-- mfilter odd (Just 1) == Just 1
-- mfilter odd (Just 2) == Nothing
Run Code Online (Sandbox Code Playgroud)

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

"foo" <$ guard (odd 3) -- Just "foo"
"foo" <$ guard (odd 4) -- Nothing
Run Code Online (Sandbox Code Playgroud)


fuz*_*fuz 7

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

find :: (a -> Bool) -> [a] -> Maybe a
Run Code Online (Sandbox Code Playgroud)

我怀疑你能在某个地方找到你的功能.但为什么不自己定义呢?

ifMaybe :: (a -> Bool) -> a -> Maybe a
ifMaybe f a | f a = Just a
ifMaybe _ _       = Nothing
Run Code Online (Sandbox Code Playgroud)

  • +1停止!霍格时间.:)注意Landei的答案,只是普通的老`mfilter`,是第四次打击. (4认同)
  • 使用`find`,你可以写`ifMaybe =(.return).find`.替换`mfilter`而不是`find`让它适用于任何`MonadPlus`. (3认同)

Chr*_*ris 5

使用:

(?:) (5>2) (Just 5,Nothing)
Run Code Online (Sandbox Code Playgroud)

来自Data.Bool.HT.

  • 除了保存几个字符之外,我并没有真正看到除了`if` /`then` /`else`以外的内容.你仍然不必要地重复'5`术语,不得不提`Nothing`.`mfilter`解决方案更胜一筹. (5认同)

Dan*_*ner 5

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

guard (pred x) >> return x
Run Code Online (Sandbox Code Playgroud)

这是一个非常有用的行为,我甚至ensure在我自己的一小段代码中定义了一次性(每个人都有这样的东西,对吧?;-):

ensure p x = guard (p x) >> return x
Run Code Online (Sandbox Code Playgroud)