是否存在以下操作的通用函数编程名称

时间:2014-06-17 06:05:43

标签: c# functional-programming system.reactive monads naming

通过我的C#代码中的组合,我最终得到了一个类型

IObservable<Maybe<IObservable<T>>> events;

其中Maybe是monad选项,IObservable是被动monad。

现在我想将其转换为

IObservable<Maybe<T>> flatEvents;

我认为表达了几乎相同的东西。注意我想保留可能体现的“无所事事”事件。我不想完全展平它,所以我只能在T的实例可用时看到事件。

经过一些试验和错误,我发现我可以通过

进行转换
var flatEvents =  events
            .Select(p=>p.Select(q=>q.Select(v=>v.ToMaybe()))
                        .Else(Observable.Return(None<T>.Default)))
            .Switch();

其中None<T>.Default返回空Maybe<T>

T Maybe<T>.Else(T v)提取选项monad中包含的值,如果没有,则提供替代值。

考虑到命名事情是最难的事情CS我正在寻找这个扁平化运算符的名称。我不是一个haskell程序员,但我确信我没有在这里发明任何东西,这是一种常见的投影。这有名字吗?

1 个答案:

答案 0 :(得分:5)

通过纯粹考虑类型,我发现更容易弄清楚你的设计是什么,独立于任何特定的monad。

你想要一个类型的函数:

:: Observable (Maybe (Observable a))
->
   Observable (Maybe a)

其中Maybe是monad,Observable是monad。

由于monad是一个通用接口,我们确实有:

:: (Monad m, Monad t) => m (t (m a)) -> m (t a)

从这种类型我们可以看到它是一种分布在上面的连接 内在的monad m

一些相关类型:

join :: Monad m => m (m a) -> m a

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

事实上,它看起来非常像内部组件上的fmap序列,其次是 通过连接 - 具有几乎正确的类型,假设t在Traversable中(如 以及Monad):

> :t join . fmap T.sequence
    :: (Monad m, Functor m, Traversable t)
       => m (t (m a)) -> m (t a)

所以我们的类型。 m (t (m a))m (t a)。完美。

所以如果你真的需要这个名字,那就是joinSequence或者 一些东西。但也许它不需要名字。