【问题标题】:flatmap Lists and Maybesflatmap 列表和可能
【发布时间】:2012-03-17 19:06:09
【问题描述】:

我正在寻找可以同时映射和展平列表和可能的代码。我在this topic找到了这样一个flatMap-function:

flatMap :: (t -> [a]) -> [t] -> [a]
flatMap _ [] = []
flatMap f (x:xs) = f x ++ flatMap f xs

这很好用:

> flatMap id [[],[1,2],[3],[],[4,5,6]]
[1,2,3,4,5,6]

唯一的问题是它不适用于Maybes。相反,我必须使用Data.Maybe.mapMaybe:

> Data.Maybe.mapMaybe id [Just 1, Nothing, Just 2, Just 3, Nothing]
[1,2,3]

是否有一个内置函数可以同时处理 Lists 和 Maybes(可能还有一些其他类型)?

【问题讨论】:

标签: haskell


【解决方案1】:

我认为Data.Foldable 可能是您正在寻找的:

> let flatMap f = concatMap (Data.Foldable.toList . f)
> :t flatMap
flatMap :: Data.Foldable.Foldable t => (a -> t b) -> [a] -> [b]
> flatMap id [[],[1,2],[3],[],[4,5,6]]
[1,2,3,4,5,6]
> flatMap id [Just 1, Nothing, Just 2, Just 3, Nothing]
[1,2,3]

【讨论】:

  • Data.Foldable 中已经有一个函数,叫做foldMap
  • @dflemstr:如何才能让它与 Maybe 一起工作? foldMap id [Just 1] 产生错误。
  • 当我说foldMapflatMap 相同时,我有点撒谎:foldMap 可以返回 any 可附加类型,而不仅仅是列表。您映射的函数的返回类型决定了外部函数返回的可附加类型。 id 函数返回一个Maybe,所以foldMap 试图返回它。但是,Maybe 不像在 Scala 中那样是一个项目的集合。当您执行mappend (Just [4]) (Just [5]) 时,它变为Just [4, 5]。如果将其与列表进行比较,mappend [[4]] [[5]] 将变为 [[4], [5]]。 (待续……)
  • 因此,在 Haskell 中,如果您附加两个 Justs,则不会丢弃第二个元素(就像在 Scala 中一样);附加了Justs 中的元素。由于您无法附加 Ints,因此您的代码失败了。如果要返回列表,则需要将 id 替换为 toList。您还可以创建一个新的Maybe-like 类型,其行为类似于Scala 的Option 在追加内容时所做的。最后,您可以跳过使用Maybes 并只使用一个元素的列表,这还不错。
  • @ErikAllik 在 Haskell 中,“附加”在这种情况下(在 Monoid 或半群的意义上)意味着任何关联操作。对于Maybemappend (Just (Sum 1)) (Just (Sum 2)) == Just (mappend (Sum 1) (Sum 2)) == Just (Sum 3)。您给出的操作不会作为mappend 的可能实现进行类型检查(类型为mappend :: Monoid m => m -> m -> m)。现在,请注意,有这三种可能的实现类型检查并且是关联的。另外两个提供为FirstLast newtypes。 catMaybes :: [Maybe a] -> [a] 与您所描述的相似。
猜你喜欢
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
相关资源
最近更新 更多