【发布时间】:2013-04-21 16:47:07
【问题描述】:
在 Haskell 中,我们有 filterM 函数。它的源代码是:
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filterM _ [] = return []
filterM p (x:xs) = do
flg <- p x
ys <- filterM p xs
return (if flg then x:ys else ys)
从do符号翻译:
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filterM _ [] = return []
filterM p (x:xs) = p x >>= \flg ->
filterM p xs >>= \ys ->
return(if flg then x:ys else ys)
据我所知,Haskell 中列表上的 >>= 和 C# 中 IEnumerable 上的 SelectMany 是相同的操作,因此,这段代码应该可以正常工作:
public static IEnumerable<IEnumerable<A>> WhereM<A>(this IEnumerable<A> list, Func<A, IEnumerable<bool>> predicate)
{
// Like Haskells null
if (list.Null())
{
return new List<List<A>> {new List<A>()};
}
else
{
var x = list.First();
var xs = list.Tail(); // Like Haskells tail
return new List<IEnumerable<A>>
{
predicate(x).SelectMany(flg => xs.WhereM(predicate).SelectMany(ys =>
{
if (flg)
{
return (new List<A> {x}).Concat(ys);
}
else
{
return ys;
}
}))
};
}
}
但它不起作用。谁能指出这里出了什么问题?
【问题讨论】:
-
请定义“它不起作用”,即显示错误。
标签: c# linq haskell functional-programming monads