/// <summary>
 /// Used within the Strategy.Match function to provide a default Directive if the
 /// Exception that caused the failure doesn't match any of the previous With clauses.
 /// </summary>
 /// <param name="directive">Directive to use</param>
 /// <returns>Strategy computation as a State monad</returns>
 public static State <Exception, Option <Directive> > Otherwise(Directive directive) =>
 Otherwise(_ => directive);
 /// <summary>
 /// Used within the Strategy.Match function to match an Exception to a Directive.
 /// Use the function's generic type to specify the type of Exception to match.
 /// </summary>
 /// <typeparam name="TException">Type of Exception to match</typeparam>
 /// <param name="directive">Directive to use if the Exception matches TException</param>
 /// <returns>Strategy computation as a State monad</returns>
 public static State <Exception, Option <Directive> > With <TException>(Directive directive) where TException : Exception =>
 With <TException>(_ => directive);
 /// <summary>
 /// Always return this Directive in the final StrategyDecision
 /// </summary>
 /// <param name="directive">Directive to return</param>
 /// <returns>Strategy computation as a State monad</returns>
 public static State <StrategyContext, Unit> Always(Directive directive) =>
 Match(Otherwise(directive));
 internal static State <Directive, Option <MessageDirective> > When(MessageDirective directive, Directive dir) =>
 When(_ => directive, dir);
 internal static State <Directive, Option <MessageDirective> > When(Func <Directive, MessageDirective> map, Directive dir) =>
 from directive in get <Directive>()
 let typeMatch = dir.GetType().GetTypeInfo().IsAssignableFrom(directive.GetType().GetTypeInfo())
                 select typeMatch
         ? Some(map(directive))
         : None;
 /// <summary>
 /// Used within the Strategy.Match function to match an Exception to a Directive.
 /// Use the function's generic type to specify the type of Exception to match.
 /// </summary>
 /// <typeparam name="TException">Type of Exception to match</typeparam>
 /// <param name="directive">Directive to use if the Exception matches TException</param>
 /// <returns>Strategy computation as a State monad</returns>
 internal static State <Exception, Option <Directive> > With(Directive directive, Type exceptionType) =>
 With(_ => directive, exceptionType);