Skip to content

Instantly share code, notes, and snippets.

@felipegtx
Created August 3, 2015 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felipegtx/bcd7ff25a38ed9cc6f63 to your computer and use it in GitHub Desktop.
Save felipegtx/bcd7ff25a38ed9cc6f63 to your computer and use it in GitHub Desktop.
Some more monads
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TDD.CalculatorImpl;
namespace TDD.UnityTests
{
[TestClass]
public class CaculatorTests
{
private ICalculator _calculator;
[TestInitialize]
public void Initialize()
{
_calculator = new Calculator();
}
[TestMethod, Description("When zero is provided as divisor, an exception should be thrown")]
public void Division_By_Zero_Should_Return_A_Typed_Exception()
{
bool threwException = false;
try
{
_calculator.Divide(4, 0);
}
catch (DivideByZeroException e)
{
threwException = true;
}
Assert.IsTrue(threwException);
}
[TestMethod, Description("When valid parameters are provided, the calculation should work just fine")]
public void Simple_Division()
{
Assert.AreEqual(2, _calculator.Divide(4, 2));
}
[TestMethod, Description("Simple multiplication arithmetic")]
public void Simple_Multiply()
{
Assert.AreEqual(4, _calculator.Multiply(2, 2));
}
[TestMethod, Description("Combinatory composition over basic operations")]
public void Operation_Interopability_Combination()
{
Func<int, int, int> multiplication = _calculator.Multiply;
Func<int, int, int> division = _calculator.Divide;
int x = 10, y = 2, z = 25, w = 5;
var equation = division.Then(multiplication).Then(division);
Assert.AreEqual((x / y) * (z / w), equation(x, y)(z, w));
}
[TestMethod, Description("Combinatory composition over basic operations - 1")]
public void Operation_Interopability_Combination1()
{
Func<int, int, int> multiplication = _calculator.Multiply;
Func<int, int, int> division = _calculator.Divide;
int x = 10, y = 2, z = 25, w = 5, d = 2;
var eq0 = division.Then(multiplication);
var eq1 = multiplication.Then(division);
var equation = eq0.Then(eq1);
Assert.AreEqual(((x / y) * (z * w)) / d, equation(x, y)(z, w)(d));
}
[TestMethod, Description("Combinatory composition over basic operations - 2")]
public void Operation_Interopability_Combination2()
{
Func<int, int, int> multiplication = _calculator.Multiply;
Func<int, int, int> division = _calculator.Divide;
int x = 10, y = 2, z = 25, w = 5, d = 2;
var c = new Calculator();
var eq0 = division.Then(multiplication).Then(multiplication);
var equation = eq0.Then(division.WithScope(d));
Assert.AreEqual(((x / y) * (z * w)) / d, equation(x, y)(z, w));
}
[TestMethod, Description("Combinatory composition over basic operations - 3")]
public void Operation_Interopability_Combination3()
{
Func<int, int, int> multiplication = _calculator.Multiply;
Func<int, int, int> division = _calculator.Divide;
int x = 10, y = 2, z = 25, w = 5, d = 2, d1 = 15;
var c = new Calculator();
var eq0 = division.Then(multiplication);
var eq1 = multiplication.Then(division);
var equation1 = eq0.Then(eq1)(x, y).Then(multiplication);
Assert.AreEqual(((x / y) * (z * w)) / (d * d1), equation1(z, w)(d, d1));
}
}
}
namespace TDD.CalculatorImpl
{
public sealed class Calculator : ICalculator
{
public int Divide(int dividend, int divisor)
{
return dividend / divisor;
}
public int Multiply(int x, int y)
{
return x * y;
}
}
}
using System;
namespace TDD.CalculatorImpl
{
public interface ICalculator
{
int Divide(int dividend, int divisor);
int Multiply(int x, int y);
}
}
using System;
namespace TDD.CalculatorImpl
{
public static class MonadicExtensions
{
public static Func<SomeType, SomeType, Func<SomeType, SomeType>> Then<SomeType>(this Func<SomeType, SomeType, SomeType> f1, Func<SomeType, SomeType, SomeType> f2)
{
return (x, y) => z => f2(f1(x, y), z);
}
public static Func<SomeType, SomeType, Func<SomeType, SomeType, SomeType>> Then<SomeType>(this Func<SomeType, SomeType,
Func<SomeType, SomeType>> f1, Func<SomeType, SomeType, SomeType> f2)
{
return (x, y) => (z, w) => f1(x, y)(f2(z, w));
}
public static Func<SomeType, SomeType, Func<SomeType, SomeType, SomeType>> Then<SomeType>(this Func<SomeType, SomeType,
Func<SomeType, SomeType, SomeType>> f1, Func<SomeType, SomeType> f2)
{
return (x, y) => (z, w) => f2(f1(x, y)(z, w));
}
public static Func<SomeType, SomeType, Func<SomeType, SomeType, Func<SomeType, SomeType>>> Then<SomeType>(this Func<SomeType, SomeType, Func<SomeType, SomeType>> eq0,
Func<SomeType, SomeType, Func<SomeType, SomeType>> eq1)
{
return (x, y) => (w, z) => eq1(eq0(x, y)(w), z);
}
public static Func<SomeType, SomeType> WithScope<SomeType>(this Func<SomeType, SomeType, SomeType> f1, SomeType y)
{
return x => f1(x, y);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment