Skip to content

Instantly share code, notes, and snippets.

@jb55
Created October 25, 2011 18:22
Show Gist options
  • Save jb55/1313735 to your computer and use it in GitHub Desktop.
Save jb55/1313735 to your computer and use it in GitHub Desktop.
Haskellish typeclass constraints in c#!
public static class InvoiceMixins
{
public static IEnumerable<OrderItem> GetTaxableOrderItems(this IOrderItems invoice) {
if (invoice.GetOrderItems() == null) return new OrderItem[] { };
return invoice.GetOrderItems().Where(oi => !oi.IsTaxFree);
}
// SubTotalSub :: (IExtendedPrice a) => a -> IEnumerable<OrderItem> -> decimal
public static decimal SubTotalSum<T>(this T invoice, IEnumerable<OrderItem> orderItems)
where T : IExtendedPrice {
return orderItems.Sum(oi => invoice.GetRelevantExtendedPrice(oi));
}
// CalculateTaxes :: (IOrderItems a, IRawShipping a, IExtendedPrice a) => a -> Program -> Address -> IEnumerable<Tax>
public static IEnumerable<CalculatedTax> CalculateTaxes<T>(this T invoice, Program program, Address destination, IEnumerable<Tax> taxes)
where T : IOrderItems, IRawShipping, IExtendedPrice {
return OrderService.CalculateTaxes(program, destination, invoice, taxes);
}
// GetTaxableSubTotalWithShipping :: (IRawShipping a, IExtendedPrice a, IOrderItems a) => a -> Program -> decimal
public static decimal GetTaxableSubTotalWithShipping<T>(this T invoice, Program program)
where T : IRawShipping, IExtendedPrice, IOrderItems {
return invoice.GetTaxableSubTotal() + invoice.GetShippingHandling(program);
}
// GetTaxableSubTotal :: (IOrderItems a, IExtendedPrice a) => a -> decimal
public static decimal GetTaxableSubTotal<T>(this T invoice)
where T : IOrderItems, IExtendedPrice {
var taxableOrderItems = GetTaxableOrderItems(invoice);
return taxableOrderItems == null ? 0 : invoice.SubTotalSum(taxableOrderItems);
}
// GetSubTotal :: (IOrderItems a, IExtendedPrice a) => a -> decimal
public static decimal GetSubTotal<T>(this T invoice)
where T : IOrderItems, IExtendedPrice {
var orderItems = invoice.GetOrderItems();
return orderItems == null ? 0 : invoice.SubTotalSum(orderItems);
}
public static decimal GetShippingHandling(this IRawShipping invoice, Program program) {
if (program == null || string.IsNullOrEmpty(program.DatabaseName)) return invoice.GetRawShippingHandling();
return UniversalBackend.ProgramIgnoresShippingHandling(program) ? 0 : invoice.GetRawShippingHandling();
}
}
public interface IOrderItems {
IEnumerable<OrderItem> GetOrderItems();
}
public interface IRawShipping {
decimal GetRawShippingHandling();
}
public interface IExtendedPrice {
decimal GetRelevantExtendedPrice(OrderItem oi);
}
@jb55
Copy link
Author

jb55 commented Oct 25, 2011

Any type which satisfies any of the required type constraints gain that extension method! Neat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment