/// <summary> /// Map both the input and output of a decoder to /// produce a new decoder. /// </summary> public static Decoder <TRaw2, T2> Dimap <TRaw1, T1, TRaw2, T2>( this Decoder <TRaw1, T1> decoder, [NotNull] Func <TRaw2, TRaw1> f, [NotNull] Func <T1, T2> g) { if (f == null) { throw new ArgumentNullException(nameof(f)); } if (g == null) { throw new ArgumentNullException(nameof(g)); } return(new Decoder <TRaw2, T2>((id, x) => decoder.Run(id, f(x)).Map(g), decoder.Id)); }
/// <summary> /// Return a new Decoder computed from the result of the first. /// </summary> public static Decoder <TRaw, T2> Bind <TRaw, T1, T2>( this Decoder <TRaw, T1> decoder, [NotNull] Func <T1, Decoder <TRaw, T2> > f) { if (f == null) { throw new ArgumentNullException(nameof(f)); } return(new Decoder <TRaw, T2>( (id, x) => from result1 in decoder.Run(id, x) from result2 in f(result1).Run(id, x) select result2, decoder.Id)); }
/// <summary> /// Create a Decoder that will select the first succesful result, or /// the last failure. /// </summary> public static Decoder <TRaw, T> Or <TRaw, T>( this Decoder <TRaw, T> decoder1, Decoder <TRaw, T> decoder2) { return(new Decoder <TRaw, T>((id, x) => decoder1.Run(id, x) || decoder2.Run(id, x))); }