/// <summary> /// A raw Html version of string.Format. This returns Html as text and /// not an HtmlString for easier manipulation. /// </summary> /// <param name="format">The format for the string this includes html</param> /// <param name="args"></param> /// <exception cref="FormatException">Thrown when the indexes in the format /// string are larger than the number of arguments passed.</exception> /// <returns></returns> public static string HtmlFormatRaw(this string format, params object[] args) { const string FormatSyntax = @"{(?<index>\d+)(?<rest>(?:,\-?\d+)?(?:\:\w+)?)}"; var func = new Func<object[], Match, string>(HtmlFormatter); var eval = new MatchEvaluator(func.Curry(args)); return Regex.Replace(format, FormatSyntax, eval); }
public static Task <Func <T2, R> > Map <T1, T2, R> (this Task <T1> @this, Func <T1, T2, R> func) => @this.Map(func.Curry());
public static Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, Option <TResult> > OnExceptionNone <T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, Option <TResult> > func) { return((x1, x2, x3, x4, x5, x6, x7, x8, x9) => func.Curry()(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8).OnExceptionNone()(x9)); }
public static Func <T1, T2, T3, Option <TResult> > OnExceptionNone <T1, T2, T3, TResult>(this Func <T1, T2, T3, Option <TResult> > func) { return((x1, x2, x3) => func.Curry()(x1)(x2).OnExceptionNone()(x3)); }
public static Maybe <Func <T2, Func <T3, Func <T4, TResult> > > > Map <T1, T2, T3, T4, TResult>( this Maybe <T1> maybe, Func <T1, T2, T3, T4, TResult> func) => maybe.Map(func.Curry());
public static IO <R> LiftA <A, B, C, D, E, F, G, R>(this Func <A, B, C, D, E, F, G, R> @this, IO <A> a, IO <B> b, IO <C> c, IO <D> d, IO <E> e, IO <F> f, IO <G> g) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e).Apply(f).Apply(g);
public static IO <R> LiftA <A, B, C, R>(this Func <A, B, C, R> @this, IO <A> a, IO <B> b, IO <C> c) => @this.Curry().Map(a).Apply(b).Apply(c);
//public static IEnumerable<R> _Map<T, R> // (this IEnumerable<T> list, Func<T, R> func) //{ // foreach (var item in list) yield return func(item); //} //public static IEnumerable<T> Where<T>(this IEnumerable<T> list // , Func<T, bool> predicate) //{ // foreach (var item in list) if (predicate(item)) yield return item; //} public static IEnumerable <Func <T2, R> > Map <T1, T2, R>(this IEnumerable <T1> list , Func <T1, T2, R> func) => list.Map(func.Curry());
public static Lazy <R> LiftA <A, B, C, R>(this Func <A, B, C, R> @this, Lazy <A> a, Lazy <B> b, Lazy <C> c) => @this.Curry().Map(a).Apply(b).Apply(c);
public static Lazy <R> LiftA <A, B, C, D, E, F, G, H, I, J, R>(this Func <A, B, C, D, E, F, G, H, I, J, R> @this, Lazy <A> a, Lazy <B> b, Lazy <C> c, Lazy <D> d, Lazy <E> e, Lazy <F> f, Lazy <G> g, Lazy <H> h, Lazy <I> i, Lazy <J> j) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e).Apply(f).Apply(g).Apply(h).Apply(i).Apply(j);
/// <summary> /// Lifts source function to IValidation context /// </summary> /// <param name="source">Source function</param> /// <returns>Source function lifted to IValidation context</returns> public static Func <IValidation <T1>, IValidation <T2>, IValidation <T3>, IValidation <T4>, IValidation <R> > Lift <T1, T2, T3, T4, R>(this Func <T1, T2, T3, T4, R> source) { var sourceCurried = source.Curry(); return((x1, x2, x3, x4) => x1.Select(sourceCurried).Apply(x2).Apply(x3).Apply(x4)); }
static void Main(string[] args) { var authors = new List <Option <Author> >(); for (var i = 1; i < 100; i++) { authors.Add(new Some <Author>(Author.Create(NonNullValue <string> .Create($"Author {i}"), DateTime.Now.AddDays(i)))); } // search example var item = authors .Where(z => z.Content.Name.Content == "Khurram") .DefaultIfEmpty(new Option <Author>()) .Single(); try { var addedAuthor = item.Match(z => z, () => { var newAuthor = Author.Create(NonNullValue <string> .Create("Khurram"), DateTime.Now); authors.Add(new Some <Author>(newAuthor)); return(newAuthor); }); WriteLine($"author:{addedAuthor.Name.Content},Date of publish:{addedAuthor.DateOfPublish}"); } catch (Exception err) { WriteLine(err.Message); } // Map , Bind examples foreach (int v in new [] { 3, 4, 5, 6, 7, 8, 9 }.Map1(i => i * i)) { WriteLine($"Square value:{v}"); } var name = new Option <string>("Khurram Shahzad"); Func <string, string> message = m => $"welcome {m}"; WriteLine(name.Map1(message).Content); var _ = None.Instance; WriteLine(_.Map1(message).Content); // For Each example new [] { 3, 4, 5, 6, 7, 8, 9 } .Map1(i => i * i) .ForEach(WriteLine); // Bind example WriteLine($"Your age is : {getAge().Content}"); Age getAge() => "Input age:" .Prompt() .Parse() .Bind(Age.Of) .Match(x => x, () => getAge()); TasksExample(); Func <string, string, string> greet = (a, b) => $"{a}-{b}"; var applyEx = greet.Apply("hello"); var curryingEx = greet.Curry(); WriteLine(applyEx("boy")); WriteLine(curryingEx("cool")("boy")); }
public static void CurryingHelperExtenion() { Func <int, int, int> add = (x, y) => x + y; Func <int, Func <int, int> > curriedAdd = add.Curry(); }
public static void RunSample() { var bk = new Book("Expert F#", "Don Syme", 55.99, "Computer Science"); const double discountRate = 0.1; const double taxRate = 0.055; const double promotionCode = 0.05; //our base multiplication function Func <double, double, double> multiply = (x, y) => x * y; //so now we've got a basic multiplication function. we can call it with two arguments, like this: var number = multiply(2, 3); //we could use this to calculate our discount/promotion rates if we wanted... var priceWithDiscount = multiply(bk.Price, 1 - discountRate); var priceWithDiscountAndPromotion = multiply(priceWithDiscount, 1 - promotionCode); var priceWithDiscountAndPromotionAndTax = multiply(priceWithDiscountAndPromotion, 1 + taxRate); //we probably wouldn't do it like that of course. we might do something more like this: var finalPrice = multiply(1 + taxRate, multiply(1 - promotionCode, multiply(1 - discountRate, bk.Price))); //bleh. in OO, this is the type of logic we'd encapsulate behind a class. with functional constructs, we can encapsulate/compose //behaviors with our functions! what we need are functions for each step in this process, and we can get them with partial application //All the generics make the signatures confusing... but take a look at the Apply operator. We call Apply on a Func<T1, T2, TResult> //We pass in an argument of T1 - kind of like this: someFunc<T1,T2,TResult>.Apply(T1 someArg). This will return another //function, that will look sort of like this: newFunc<someArg,T2,TResult>; so someArg is now "stuck" to newFunc, and newFunc is now just expecting //a single argument, which it will apply to the argument we've fixed to the function var calcDiscountedRate = multiply.Apply(1 - discountRate); var calcPromotionalRate = multiply.Apply(1 - promotionCode); var calcTax = multiply.Apply(1 + taxRate); /*so now we've got a set of functions representing the full set of operations we want to apply to get a book's final price. * We've made them by "sticking" their first arguments to our constants. Neato! now we can call each of them like this, with a single argument: */ priceWithDiscount = calcDiscountedRate(bk.Price); //and we can also chain them together like this: calcTax(calcPromotionalRate(calcDiscountedRate(bk.Price))); //that's all well and good, but what would be SUPER SWEET is if we could COMPOSE all these into one function, chain them all //into a single pipeline we could use to get our net price... oh wait we can: var calcNetPrice = calcDiscountedRate .ForwardCompose(calcPromotionalRate) .ForwardCompose(calcTax); var netPrice = calcNetPrice(bk.Price); //we call ForwardCompose on Func, kind of like Apply... it'll bascially call functions on the results of other functions, like our standard chain above //we can easily add more functions into this pipeline if we have to //we can accomplish the same thing with Curry. First we "curry" our multiply function... var curriedMult = multiply.Curry(); //this gives us a function we can call with one argument at a time: calcDiscountedRate = curriedMult(1 - discountRate); calcPromotionalRate = curriedMult(1 - promotionCode); calcTax = curriedMult(1 + taxRate); calcNetPrice = calcDiscountedRate .ForwardCompose(calcPromotionalRate) .ForwardCompose(calcTax); }
public static Lazy <R> LiftA <A, B, C, D, E, R>(this Func <A, B, C, D, E, R> @this, Lazy <A> a, Lazy <B> b, Lazy <C> c, Lazy <D> d, Lazy <E> e) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e);
/// <summary> /// Implements an applicative functor on Option /// </summary> public static Option <TResult> ApplicativeFunctor <T1, T2, TResult>(this Option <T1> t1, Option <T2> t2, Func <T1, T2, TResult> f) { return(t2.Applicative(t1.Map(f.Curry()))); }
public static Lazy <R> LiftA <A, B, C, D, E, F, G, R>(this Func <A, B, C, D, E, F, G, R> @this, Lazy <A> a, Lazy <B> b, Lazy <C> c, Lazy <D> d, Lazy <E> e, Lazy <F> f, Lazy <G> g) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e).Apply(f).Apply(g);
Map <T1, T2, T3, R>(this IEnumerable <T1> opt, Func <T1, T2, T3, R> func) => opt.Map(func.Curry());
/// <summary> /// Creates a new non parameter function by partial applies the <paramref name="parameter"/> and <paramref name="parameter2"/> into the <paramref name="function"/>. /// </summary> /// <typeparam name="T">The type of the first parameter of <paramref name="function"/>.</typeparam> /// <typeparam name="T2">The type of the second parameter of <paramref name="function"/>.</typeparam> /// <typeparam name="TResult">The type of the value returned by <paramref name="function"/>.</typeparam> /// <param name="function">The input function.</param> /// <param name="parameter">The first input parameter to partial apply.</param> /// <param name="parameter2">The second input parameter to partial apply.</param> /// <returns>Returns a partial applied function.</returns> public static Func <TResult> PartialApply <T, T2, TResult>(Func <T, T2, TResult> function, T parameter, T2 parameter2) => () => function.Curry()(parameter)(parameter2);
public static IO <R> LiftA <A, B, C, D, E, R>(this Func <A, B, C, D, E, R> @this, IO <A> a, IO <B> b, IO <C> c, IO <D> d, IO <E> e) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e);
/// <summary> /// Creates a new two parameters function by partial applies the <paramref name="parameter"/> into the <paramref name="function"/>. /// </summary> /// <typeparam name="T">Type of <paramref name="function"/> parameter.</typeparam> /// <typeparam name="T2">Type of <paramref name="function"/> second parameter.</typeparam> /// <typeparam name="T3">Type of <paramref name="function"/> third parameter.</typeparam> /// <typeparam name="TResult">Type of <paramref name="function"/> return.</typeparam> /// <param name="function">The input function.</param> /// <param name="parameter">The input parameter to partial apply.</param> /// <returns>Returns a partial applied function</returns> public static Func <T2, T3, TResult> PartialApply <T, T2, T3, TResult>(Func <T, T2, T3, TResult> function, T parameter) => (parameter2, parameter3) => function.Curry()(parameter)(parameter2)(parameter3);
public static IO <R> LiftA <A, B, C, D, E, F, G, H, I, J, R>(this Func <A, B, C, D, E, F, G, H, I, J, R> @this, IO <A> a, IO <B> b, IO <C> c, IO <D> d, IO <E> e, IO <F> f, IO <G> g, IO <H> h, IO <I> i, IO <J> j) => @this.Curry().Map(a).Apply(b).Apply(c).Apply(d).Apply(e).Apply(f).Apply(g).Apply(h).Apply(i).Apply(j);
public static Try <Func <T2, R> > Map <T1, T2, R> (this Try <T1> @try, Func <T1, T2, R> func) => @try.Map(func.Curry());
public static Option <Func <T2, R> > Map <T1, T2, R> (this Option <T1> @this, Func <T1, T2, R> func) => @this.Map(func.Curry());
public static Func <T2, T3, TResult> Partial <T1, T2, T3, TResult>(this Func <T1, T2, T3, TResult> func, T1 arg1) { return(func.Curry()(arg1)); }
public static Func <T1, T2, T3, T4, T5, T6, Option <TResult> > OnExceptionNone <T1, T2, T3, T4, T5, T6, TResult>(this Func <T1, T2, T3, T4, T5, T6, Option <TResult> > func) { return((x1, x2, x3, x4, x5, x6) => func.Curry()(x1)(x2)(x3)(x4)(x5).OnExceptionNone()(x6)); }
/// <summary> /// Implements an applicative functor on Option /// </summary> public static Option <TResult> ApplicativeFunctor <T1, T2, T3, T4, T5, TResult>(this Option <T1> t1, Option <T2> t2, Option <T3> t3, Option <T4> t4, Option <T5> t5, Func <T1, T2, T3, T4, T5, TResult> f) { return(t5.Applicative(t4.Applicative(t3.Applicative(t2.Applicative(t1.Map(f.Curry())))))); }
public static Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, Option <TResult> > OnExceptionNone <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, Option <TResult> > func) { return((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => func.Curry()(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14).OnExceptionNone()(x15)); }
/// <summary> /// Implements an applicative functor on Option /// </summary> public static Option <TResult> ApplicativeFunctor <T1, T2, T3, T4, T5, T6, T7, T8, TResult>(this Option <T1> t1, Option <T2> t2, Option <T3> t3, Option <T4> t4, Option <T5> t5, Option <T6> t6, Option <T7> t7, Option <T8> t8, Func <T1, T2, T3, T4, T5, T6, T7, T8, TResult> f) { return(t8.Applicative(t7.Applicative(t6.Applicative(t5.Applicative(t4.Applicative(t3.Applicative(t2.Applicative(t1.Map(f.Curry()))))))))); }
public static Try <TFailure, Func <TB, NewTSuccess> > Map <TFailure, TSuccess, TB, NewTSuccess>( this Try <TFailure, TSuccess> @this, Func <TSuccess, TB, NewTSuccess> func ) => @this.Map(func.Curry());
/// <summary> /// lift a 4-argument function over 4 AccResults. (If all AccResults are IsSuccess, apply the function to the success values; else results in Failure) /// </summary> public static AccResult <E, Z> LiftA4 <A, B, C, D, E, Z>(Func <A, B, C, D, E> f, AccResult <A, Z> a, AccResult <B, Z> b, AccResult <C, Z> c, AccResult <D, Z> d) { return(a.Map(f.Curry()).Apply(b).Apply(c).Apply(d)); }