public void TupleTest() { bool isExecuted = false; ValueTuple <int> one = new ValueTuple <int>(1); ValueTuple <int> two = new ValueTuple <int>(2); Func <int, Func <int, int> > add = x => y => { isExecuted = true; return(x + y); }; ValueTuple <int> query = from x in one from y in two from _ in one select add(x)(y); Assert.IsTrue(isExecuted); // Immediate execution. Assert.AreEqual(1 + 2, query.Item1); // Execution. // Monad law 1: m.Monad().SelectMany(f) == f(m) Func <int, ValueTuple <int> > addOne = x => (x + 1).ValueTuple(); ValueTuple <int> left = 1.ValueTuple().SelectMany(addOne, False); ValueTuple <int> right = addOne(1); Assert.AreEqual(left.Item1, right.Item1); // Monad law 2: M.SelectMany(Monad) == M ValueTuple <int> M = 1.ValueTuple(); left = M.SelectMany(ValueTupleExtensions.ValueTuple, False); right = M; Assert.AreEqual(left.Item1, right.Item1); // Monad law 3: M.SelectMany(f1).SelectMany(f2) == M.SelectMany(x => f1(x).SelectMany(f2)) Func <int, ValueTuple <int> > addTwo = x => (x + 2).ValueTuple(); left = M.SelectMany(addOne, False).SelectMany(addTwo, False); right = M.SelectMany(x => addOne(x).SelectMany(addTwo, False), False); Assert.AreEqual(left.Item1, right.Item1); }