次のパターンは、Haskellコードで非常に頻繁に表示されます。それを書くためのより短い方法はありますか?
if pred x
then Just x
else Nothing
次のパターンは、Haskellコードで非常に頻繁に表示されます。それを書くためのより短い方法はありますか?
if pred x
then Just x
else Nothing
あなたが探しているのmfilter
はControl.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
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
guard
この動作を実現するために使用できます。
guard (pred x) >> return x
これは非常に一般的に便利な動作でありensure
、私自身の小さなコード スイートで 1 回限りのコードを定義したこともあります (誰もがそのようなものを持っていますよね? ;-):
ensure p x = guard (p x) >> return x
使用する:
(?:) (5>2) (Just 5,Nothing)
Data.Bool.HT から。
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
わからない場合、これはあまり深刻な答えではありません。他の人はもう少し洞察力に富んでいますが、「このコードを短くしてください」という皮肉な反応に抵抗できませんでした。
通常、私は非常に一般的なコードの大ファンですが、実際には、この正確な関数が十分に有用であり、 に特化しているため、 、 などMaybe
を使用する代わりに使用し続けています。guard
mfilter
私が使用する名前は です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
、述語の結果を示すために使用されます。
このような特殊なバージョンの場合、短くするためにできることはあまりありません。それはすでにかなり単純です。簡潔であることと、コードを文字数のためにゴルフすることとの間には微妙な境界線があります。この単純なものについては、それを「改善」しようとすることを本当に心配しません...