import { tagged } from "daggy"; const First = tagged("First", ["val"]); First.prototype.concat = function(that) { return this; }; const Min = tagged("Min", ["val"]); Min.prototype.concat = function(that) { return Min(Math.min(this.val, that.val)); }; const Any = tagged("Any", ["val"]); Any.prototype.concat = function(that) { return Any(this.val || that.val); }; const Tuple4 = tagged("Tuple4", ["a", "b", "c", "d"]); Tuple4.prototype.concat = function(that) { return Tuple4( this.a.concat(that.a), this.b.concat(that.b), this.c.concat(that.c), this.d.concat(that.d) ); }; const Customer = tagged("Customer", [ "name", "favouriteThings", "registrationDate", "hasMadePurchase" ]); const myStrategy = { to: customer => Tuple4( First(customer.name), customer.favouriteThings, Min(customer.registrationDate), Any(customer.hasMadePurchase) ), from: ({ a, b, c, d }) => Customer(a.val, b, c.val, d.val) }; const merge = strategy => x => y => strategy.from(strategy.to(x).concat(strategy.to(y))); const Tom1 = Customer("Tom", ["socks"], 100000, false); const Tom2 = Customer("TomH", ["gloves"], 90000, true); // { name: 'Tom' // , favouriteThings: ['socks', 'gloves'] // , registrationDate: 90000 // , hasMadePurchase: true // } merge(myStrategy)(Tom1)(Tom2);