16

次のパターンは、Haskellコードで非常に頻繁に表示されます。それを書くためのより短い方法はありますか?

if pred x
then Just x
else Nothing
4

6 に答える 6

28

あなたが探しているのmfilterControl.Monad

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
于 2011-09-17T09:54:49.723 に答える
7

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
于 2011-09-17T09:29:52.970 に答える
5

guardこの動作を実現するために使用できます。

guard (pred x) >> return x

これは非常に一般的に便利な動作でありensure、私自身の小さなコード スイートで 1 回限りのコードを定義したこともあります (誰もがそのようなものを持っていますよね? ;-):

ensure p x = guard (p x) >> return x
于 2011-09-17T14:26:38.440 に答える
5

使用する:

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

Data.Bool.HT から。

于 2011-09-17T10:32:49.717 に答える
1
f pred x = if pred x then Just x else Nothing

上記の定義を考えると、次のように簡単に書くことができます。

f pred x

もちろん、これは Daniel Wagnerensureや 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

わからない場合、これはあまり深刻な答えではありません。他の人はもう少し洞察力に富んでいますが、「このコードを短くしてください」という皮肉な反応に抵抗できませんでした。

于 2011-09-17T18:40:35.950 に答える
1

通常、私は非常に一般的なコードの大ファンですが、実際には、この正確な関数が十分に有用であり、 に特化しているため、 、 など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、述語の結果を示すために使用されます。

このような特殊なバージョンの場合、短くするためにできることはあまりありません。それはすでにかなり単純です。簡潔であることと、コードを文字数のためにゴルフすることとの間には微妙な境界線があります。この単純なものについては、それを「改善」しようとすることを本当に心配しません...

于 2011-09-17T19:23:03.443 に答える