2013-08-02 13 views
5

I tip bir işlev gibi olacaktır:catMaybes gibi Haskell işlev ancak sahip olan tip [Belki] -> Belki [a]

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

ör Benim fNothing hakkında çok ciddi iken bu catMaybes, Nothing görmezden hariç

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

Bu Data.Maybe içinde catMaybes :: [Maybe a] -> [a] benzer.

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

veya

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

Bir buluşsal keşif olarak - eğer tipik bir liste işlevi yazıyorsanız ve 'length' (özellikle bir kereden fazla kullanıyorsanız) ile kendinizi buluyorsanız, muhtemelen yanlış bir şey yapıyorsunuz demektir. Haskell'deki çoğu kod için uygun değil. Bu her zaman böyle değildir, ama öğrenirken, onu kullanmamanın yanından geçmelisin. :-) – shachaf

+4

Şüpheniz olduğunda, [hoogle] (http://www.haskell.org/hoogle/?hoogle=%5BMaybe+a%5D+-%3E+Maybe+%5Ba%5D). Hoogle'da [Belki a] -> Belki [a] 'aradım ve aşağıda listelenen doğru cevabı aldım ('sequence'). – aaronlevin

+1

Ben 'hoogle'd ve 'catMaybes' fark ettim. 'sequence' listedeki ilk oldu. Onu görmezden geldim çünkü bu tür 'Belki' değil, 'Monad' ve bağlantıyı tanıyamadım. – Causality

cevap

20

aradığınız işlev dizisi denir:

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

Sen hoogle kullanarak bu işlevi bulabilirsiniz: link.

Örnek:

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

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

Not: Orada biraz genelleştirilmiş olduğu Data.Traversable yılında sequenceA da, ancak Control.Monad adresinin kullanım durumu dizisi için yeterlidir.

7

Sen Control.Monad den sequence istiyorum: ("uygulamalı funktor" gibi) daha deyimsel yolu olup olmadığını (aşağıda gösterildiği gibi) bir naif bir şekilde f uygulamak, fakat merak olabilir .

(Bu ayrıca Data.Traversable yararlı bir şekilde genelleştirilmiş edilir.)

İlgili konular