2013-08-02 4 views
5

私はタイプと機能を持っているしたいと思います:catMaybesのようなHaskellでは関数が、型を有するが、[たぶん] - >たぶん、[A]

例えば
f :: [Maybe a] -> Maybe [a] 

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

それはそのcatMaybes除き、Data.MaybecatMaybes :: [Maybe a] -> [a]に似ている私のfNothingについて非常に深刻でありながら、Nothingを無視します。私は素朴な方法(下記のように)でfを実装しますが、(「応用的ファンクタ」のように)より多くの慣用的な方法があるかどうか不思議でした:

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 
+6

一般的なリスト関数を書いていて、 'length'を使って自分自身を見つけた場合(特に複数回使用する場合)、おそらく何か間違っているでしょう。 Haskellのほとんどのリストコードには適していません。それは必ずしも当てはまるわけではありませんが、あなたが学んでいるときに、あなたはそれを使用しない側で誤りを犯すべきです。 :-) – shachaf

+4

不明な点がある場合は、[google](http://www.haskell.org/hoogle/?hoogle=%5BMaybe+a%5D+-%3E+Maybe+%5Ba%5D)。私はHoogleの '[Maybe a] - > Maybe [a]'を検索し、正しい答えを以下に列挙しました( 'sequence')。 – aaronlevin

+1

私は 'それをホッとして' catMaybes'に気づいた。 'sequence'はリストの最初のものでした。私はそれが無視されました。なぜなら、タイプは「Maybe」ではなく「Monad」であり、接続を認識できませんでした。 – Causality

答えて

20

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

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からご利用の場合、シーケンスのために十分です。

関連する問題