【发布时间】:2017-06-13 21:49:30
【问题描述】:
以下代码中的sum() 已经得到a、b、c 和 10 的总和,即使 a < b(它会打印“我们搞砸了!”以表示表达式虽然不符合条件)。我尝试将Where<T>(...) 扩展方法更改为
public static IO<T> Where<T>(this IO<T> t, Func<T, bool> foo)
{
return () => (foo(t()) ? t : Combine(() => default(T), () => { Console.WriteLine("We screwed up!"); }))();
}
但它会在select a + b + c + x 上得到 NullReferenceException 异常?为什么? 没有创建空值?
class Program
{
static void Main(string[] args)
{
var A = new Monad.IO<int>(() => { Console.WriteLine("A"); return 6; });
var B = new Monad.IO<int>(() => { Console.WriteLine("B"); return 7; });
var C = new Monad.IO<int>(() => { Console.WriteLine("C"); return 10; });
var sum =
from a in A
from b in B
from c in C
let x = 10
where a > b // Should fail the whole expression and return default(T) because a < b
select a + b + c + x;
Console.WriteLine(sum());
}
}
static class Monad
{
public delegate T IO<out T>();
public static IO<R> SelectMany<S, C, R>(this IO<S> A, Func<S, IO<C>> foo, Func<S, C, R> bar)
{
var a = A();
var B = foo(a);
var b = B();
var c = bar(a, b);
return () => c;
// return () => bar(a, foo(a)());
}
public static IO<T> Combine<T>(IO<T> a, Action b)
{
return new Func<IO<T>, IO<T>>(x => { b(); return x; })(a);
}
public static IO<T> Where<T>(this IO<T> t, Func<T, bool> foo)
{
return () => (foo(t()) ? t : Combine(t, () => { Console.WriteLine("We screwed up!"); }))();
}
public static IO<R> Select<S, R>(this IO<S> s, Func<S, R> foo)
{
return () => new Func<IO<S>, R>(x => foo(x()))(s);
}
}
代码来自https://blogs.msdn.microsoft.com/alazarev/2017/05/20/fun-with-pure-c-and-monads/
【问题讨论】: