【发布时间】:2011-12-25 23:20:11
【问题描述】:
我有一个一般性问题和一个更具体的案例问题。
一般来说,如何组合不同的 monad? monad 运算符的某些组合是否允许轻松组合?还是必须编写临时方法来组合每对可能的 monad?
作为一个具体的例子,我写了一个 Maybe monad。如何使用 IEnumerable<IMaybe<T>> ?除了手动挖掘到 LINQ 扩展中的 Maybe monad(例如:select 子句中的 if(maybe.HasValue)...)之外,是否有一种“monadic”方式将两者与各自的 Bind 等 monad 操作结合起来?
否则,如果我必须编写特定的组合方法,这样的方法是否正确?
public static IEnumerable<B> SelectMany<A, B>(this IEnumerable<A> sequence, Func<A, IMaybe<B>> func)
{
return from item in sequence
let result = func(item)
where result.HasValue
select result.Value;
}
public static IEnumerable<C> SelectMany<A, B, C>(this IEnumerable<A> sequence, Func<A, IMaybe<B>> func, Func<A, B, C> selector)
{
return from item in sequence
let value = item
let maybe = func(item)
where maybe.HasValue
select selector(value, maybe.Value);
}
【问题讨论】:
-
我发现了一个非常有趣的组合 monad 的参考:heinrichapfelmus.github.com/operational/… 它提倡一种组合 monad 的通用方式。您还应该阅读这篇论文,它描述了如何以通用和可扩展的方式组合数据类型:cs.ru.nl/~wouters/Publications/DataTypesALaCarte.pdf
标签: c# ienumerable monads