public static CondAsync <A, C> Select <A, B, C>(this Cond <A, B> self, Func <B, Task <C> > map) => input => from b in self.ToAsync()(input) from c in b.Match( Some: b2 => map(b2).ContinueWith(b3 => Optional(b3.Result)), None: () => Option <C> .None.AsTask()) select c;
public static Func <A, Task <B> > Else <A, B>(this Cond <A, B> self, Task <B> Else) => input => from b in self.ToAsync()(input) from c in b.Match( Some: c1 => c1.AsTask(), None: () => Else) select c;
public static Func <Task <A>, Task <B> > ElseAsync <A, B>(this Cond <A, B> self, Func <Task <B> > Else) => input => from a in input from b in self.ToAsync()(a) from c in b.Match( Some: c1 => c1.AsTask(), None: () => Else()) select c;
public static CondAsync <A, B> All <A, B>(this Cond <A, B> self, params Func <B, Task <bool> >[] predicates) => input => from x in self.ToAsync()(input) from y in x.Match( Some: b => Tasks.ForAll(predicates.Map(p => p(b)), identity), None: () => false.AsTask()) select y ? x : None;
public static CondAsync <A, B> Any <A, B>(this Cond <A, B> self, params Func <B, Task <bool> >[] predicates) => input => from x in self.ToAsync()(input) from y in x.Match( Some: b => Tasks.Exists(predicates.Map(p => p(b)), identity), None: () => Task.FromResult(false)) select y ? x : None;
public static CondAsync <A, D> SelectMany <A, B, C, D>( this Cond <A, B> self, Func <B, CondAsync <A, C> > bind, Func <B, C, D> project) => input => from b in self.ToAsync()(input) from c in b.Match( Some: b1 => bind(b1)(input), None: () => Option <C> .None.AsTask()) select(from x in b from y in c select project(x, y));
public static CondAsync <A, B> Where <A, B>(this Cond <A, B> self, Func <B, Task <bool> > pred) => input => from b in self.ToAsync()(input) from p in b.Map(pred).IfNone(false.AsTask()) select p ? b : None;
public static CondAsync <A, B> Then <A, B>(this Cond <A, A> self, Func <A, Task <B> > f) => self.ToAsync().Select(f);