2016-11-20 91 views
8

我想創建一個將Map k [v]Data.Map.Strict)轉換爲Maybe (Map k v)的函數。有沒有更好的方法來做Map k [v] - > Maybe(Map k v)?

它的作用是這樣的:

  • 如果任何名單中沒有一個元素,則函數返回Nothing
  • 如果所有列表都只有一個元素,它將返回包含在Just中的預期映射。

我能想到的唯一的事情就是用foldrWithKey'foldlWithKey'手動執行此操作。有更好的方法嗎?

回答

18

您正在尋找traverse :: (Traverseable t, Applicative f) => (a -> f b) -> t a -> f (t b)Data.Traversable(但也在前奏)。

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

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

traverse f可能是最好理解爲sequenceA . fmap f。另一方面,sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)是一種從「Traversable」結構中拉出應用「效果」的方式。例如,可以使用sequenceA :: [IO a] -> IO [a]執行IO動作列表。或者在Maybe的情況下,如果Traversable結構中的所有元素都是Just並且如果任何元素是NothingsequenceA的結果也將是Nothing,則結果將是Just

如果您知道sequencemapMsequenceAtraverse只是其中的一般性說明。

+1

請注意,您可以概括一下justOne函數:'foldr(\ a _ - > pure a)empty ::(Alternative f,Foldable t)=> ta - > fa',它直觀地產生如果容器是空的,最右邊的元素或失敗。 – user2407038

+0

@ user2407038,最左邊。 – user3237465

+0

@ user2407038。是的,可摺疊泛化沒有問題,但我不確定「純粹」泛化是非常有用的。它是否對所有應用程序都有用(例如'ZipList'或'( - >)')?相關:https://wiki.haskell.org/Why_not_Pointed%3F – jpath

相關問題