【发布时间】:2020-03-20 01:56:42
【问题描述】:
我有一个Option<T> 实例的集合,并希望从IEnumerable<Option<T>> 转换为Option<IEnumerable<T>>
如果 ALL 选项有一个值,那么我想要一个带有收集值的 Some<IEnumerable<T>>,如果集合中的 ANY 项目是 None,那么我想要一个None<IEnumerable<T>>
这似乎是一个很常见的函数转换,但我不确定它是否存在于主流函数库中,或者它会被称为什么。似乎类似于FlatMap,但不完全是,因为我不想只过滤掉None 值。
我可以自己实现它,但想知道它是否已经作为函数构造存在。不要介意什么语言,C#、Scala、Haskell 等。
【问题讨论】:
-
是的,这是一个常见的转换,它被称为
sequence,它具有以下签名sequence[F[_] : Traverse, G[_] : Applicative, A](fga: F[G[A]]): G[F[A]](Scala 中提供的签名)。 C# 中好像你需要它,我不知道它有没有,但至少你已经知道要搜索什么了。 -
感谢@LuisMiguelMejíaSuárez!很有意思。我已经完成了一些 Scala,因此将进行调查。
-
注意,如果您在
map之后得到了该选项集合,而不是先调用map,然后再调用sequence,您可以使用traverse。traverse[F[_] : Traverse, G[_] : Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]它遵循以下相等sequence(fga) === traverse(fga)(identity)因此,您可以得出结论sequence(map(fa)(f)) === traverse(fa)(f)。 -
我不熟悉此处标记的其他语言,但这在 Haskell 中也称为
sequence- 或 sequenceA 是适用于任何Traversable持有 @987654341 的最通用形式@值。 -
酷,
sequence和traverse。看起来我有一个很好的调查起点。谢谢大家!
标签: c# scala haskell functional-programming monads