2016-11-20 14 views
8

Map k [v] (Data.Map.Strict) öğesini Maybe (Map k v) içine döndüren bir işlev oluşturmak istiyorum.Harita k [v] -> Belki (Harita k v) yapmak için daha iyi yollar var mı?

Yaptığı şey şudur: listelerin herhangi tam olarak bir unsuru yoksa

  • , işlev Nothing döndürür.
  • Listelerin tümü tam olarak bir öğeye sahipse, bir Just içine sarılmış beklenen haritayı döndürür. Aklıma

tek şey foldrWithKey' veya foldlWithKey' ile elle yapmaktır. Daha iyi yollar var mı?

cevap

18

traverse :: (Traverseable t, Applicative f) => (a -> f b) -> t a -> f (t b) ürününü Data.Traversable'dan (ayrıca Prelude'de) bulabilirsiniz.

justOne :: [a] -> Maybe a 
justOne [x] = Just x 
justOne _ = Nothing 

allJustOne :: Map k [v] -> Maybe (Map k v) 
allJustOne = traverse justOne 

traverse f muhtemelen en iyi sequenceA . fmap f olarak anlaşılmaktadır. Diğer yandan, , Traversable yapısının uygulamalı "efektlerini" çekmenin bir yoludur. Örneğin, biri sequenceA :: [IO a] -> IO [a] ile IO eylemlerinin bir listesini yürütebilir. Traversable yapısında bütün unsurları Just ve elemanların herhangi Nothing ise sequenceA sonucu da Nothing olacak Veya Maybe durumunda sonuç Just olacaktır.

Eğer sequence veya mapM biliyorsanız, sequenceA ve traverse olanların sadece genellemeler vardır.

+1

'JustOne' işlevini biraz genelleştirebileceğinizi unutmayın: 'foldr (\ a _ -> saf a) boş :: (Alternatif f, Katlanabilir t) => ta -> fa', sezgisel olarak üreten kapsayıcı boşsa en sağdaki öğe veya başarısız. – user2407038

+0

@ user2407038, en soldaki. – user3237465

+0

@ user2407038. Evet, Katlanabilir genelleme iyidir, ancak 'saf' genellemenin çok faydalı olduğundan emin değilim. Örneğin herhangi bir uygulama için yararlı ve beklenen bir şey yapar mı (ör., "ZipList" veya "(->)')? İlgili: https://wiki.haskell.org/Why_not_Pointed%3F – jpath