private static FSharpChoice <int, Errors> Positive(int a) { if (a <= 0) { return(FSharpChoice.Error <int>("Field must be positive")); } return(FSharpChoice.Ok(a)); }
/// <summary> /// Same as FSharpChoice.Validator, for demo purposes only /// </summary> /// <typeparam name="T"></typeparam> /// <param name="pred"></param> /// <param name="err"></param> /// <returns></returns> static Func <T, FSharpChoice <T, Errors> > Validator <T>(Predicate <T> pred, string err) { return(x => { if (pred(x)) { return FSharpChoice.Ok(x); } return FSharpChoice.Error <T>(err); }); }
static FSharpChoice <T, Errors> GreaterThan <T>(T value, T other, string err) where T : IComparable <T> { var valueNull = Equals(null, value); var otherNull = Equals(null, other); if (valueNull && otherNull || valueNull != otherNull || value.CompareTo(other) > 0) { return(FSharpChoice.Ok(value)); } return(FSharpChoice.Error <T>(err)); }
public void Part1() { var costDave = ClubbedToDeath.CostToEnter(Dave); Assert.AreEqual(FSharpChoice.Error <decimal>("Too old!"), costDave); var costKen = ClubbedToDeath.CostToEnter(Ken); Assert.AreEqual(FSharpChoice.Ok(5m), costKen); var costRuby = ClubbedToDeath.CostToEnter(Ruby); Assert.AreEqual(FSharpChoice.Ok(0m), costRuby); var Ruby17 = new Person( age: 17, clothes: Ruby.Clothes, sobriety: Ruby.Sobriety, gender: Ruby.Gender); var costRuby17 = ClubbedToDeath.CostToEnter(Ruby17); Assert.AreEqual(FSharpChoice.Error <decimal>("Too young!"), costRuby17); var KenUnconscious = new Person( age: Ken.Age, clothes: Ken.Clothes, gender: Ken.Gender, sobriety: Sobriety.Unconscious); var costKenUnconscious = ClubbedToDeath.CostToEnter(KenUnconscious); Assert.AreEqual(FSharpChoice.Error <decimal>("Sober up!"), costKenUnconscious); /** * The thing to note here is how the Validations can be composed together in a computation expression. * The type system is making sure that failures flow through your computation in a safe manner. */ }