5

次のタイプの関数が必要です。

f :: [Maybe a] -> Maybe [a]

例えば

f [Just 3, Just 5] == Just [3, 5]
f [Just 3, Nothing] == Nothing
f [] == Just []

を無視することを除いて、catMaybes :: [Maybe a] -> [a]inと似ていますが、 myは について非常に深刻です。(以下に示すように) 素朴な方法で実装することもできますが、もっと慣用的な方法 (「アプリケーション ファンクター」など) があるかどうか疑問に思っています。Data.MaybecatMaybesNothingfNothingf

f :: [Maybe a] -> Maybe [a]
f xs = let ys = catMaybes xs
        in if length ys == length xs 
           then Just ys
           else Nothing

また

f :: [Maybe a] -> Maybe [a]
f xs = if all isJust xs
        then catMaybes xs
        else Nothing
4

2 に答える 2

21

あなたが探している関数はシーケンスと呼ばれます:

sequence :: (Monad m) => [m a] -> m [a]

この関数は hoogle: linkを使用して見つけることができます。

例:

>>> sequence [Just 3, Just 5]
Just [3,5]

>>> sequence [] :: Maybe [Int]
Just []

注: Data.Traversableには少し一般化された sequenceA もありますが、ユース ケースではControl.Monadからのシーケンスで十分です。

于 2013-08-02T00:29:31.107 に答える
7

sequenceから欲しいControl.Monad

(これは、 にも便利な方法で一般化されていData.Traversableます。)

于 2013-08-02T00:28:45.097 に答える