寻找特殊地图功能的名称

时间:2017-05-05 20:29:26

标签: haskell

我是Haskell的新手并且正在寻找一个函数的名称(或者通常是概念的名称):

该函数有两个参数:
1.元素列表[T]
2.一个接受T的函数,并返回一个Maybe U。

该功能的输出如下:
如果列表中的所有元素都映射到Some U,则返回Some [U]。
否则,返回None。

即。如果任何映射值为null,则返回null,否则只返回映射值。

3 个答案:

答案 0 :(得分:12)

这是Traversable类中定义的traverse

traverse :: Traversable t, Applicative f => (a -> f b) -> t a -> f (t b) 
您的示例中的

t是列表,fMaybe,例如

traverse (\x -> if x < 5 then Just x else Nothing) [1,2,3]
> Just [1,2,3]

traverse (\x -> if x < 5 then Just x else Nothing) [1,2,3, 9]
> Nothing

答案 1 :(得分:5)

该功能名为traverse,来自Data.Traversable

该类型最初可能会令人惊讶,因为它非常抽象:

traverse :: (Applicative f,Traversable t) => (a -> f b) -> t a -> f (t b)

ApplicativeTraversable是两个接口(Haskell术语中的类型)。

  • 我们想要执行的效果Applicative摘要。在您的情况下,它是失败的(Maybe)但它也可能是失败原因(Either),输入/输出(IO),并发输入/输出({{3和其他许多人。

  • Traversable对容器的类型进行抽象。在您的情况下,它是一个列表([])。但是其他容器也是Traversable:有限容器,其形状独立于其自身的值。 ConcurrentlyTrees就是例子。 (Maps 不是示例,因为它们的&#34;形状&#34;取决于它们的值:将所有元素更改为相同的值将减小集合的大小。)

Traversable是支持&#34;内部迭代的容器的接口&#34;。它基本上是其他语言的forEach。但它还为您提供了一个与原始形状相同的容器,它包含转换后的值。

如果您不关心转换后的容器,相关的Sets函数将丢弃结果,并仅针对效果执行。

mapM函数是traverse的同义词,由于历史原因而存在。

答案 2 :(得分:1)

虽然Data.Traverable.traverse似乎是正确的答案,但您也可以自己实施类似的功能。

isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust _        = False

withList :: (a -> Maybe b) -> [a] -> Maybe [b]
withList f xs | all isJust js = Just (map (\(Just x) -> x) js)
              | otherwise     = Nothing
              where js = map f xs

*Main> withList (\xs -> if all (<10) xs then (Just (sum xs)) else Nothing) [[1,2,3],[4,5,6],[7,8,9]] 
Just [6,15,24]
*Main> withList (\xs -> if all (<9) xs then (Just (sum xs)) else Nothing) [[1,2,3],[4,5,6],[7,8,9]]
Nothing