Hey there,
I have a lot of functions that are very similar:
let addCustomer customerNumber firstName data =
let customer = Customer.create customerNumber firstName
{ data with Customers = data.Customers @ [ customer ] }
let addOrder orderNumber name data =
let order = Order.create orderNumber name
{ data with Orders = data.Orders @ [ order ] }
let addInvoice id amount name data =
let invoice = Invoice.create id amount name
{ data with Invoices = data.Invoices @ [ invoice ] }
I feel like there should be a way to extract the common behavior, but I am struggling to find a way.
Any ideas?
Thx
All functions as different as an apple and an orange. Outside similar, but inside no.
Yeah I don’t think there’s a lot of opportunity. If you wrote setters for each field of your data record like
module Data =
let updateCustomers fn x = { x with Customers = fn x.Customers }
let updateOrders fn x = { x with Orders = fn x.Orders }
...
then you could kinda shorten it with
let snoc x xs = xs @ [x]
let addCustomer customerNumber firstName = Data.updateCustomers (snoc (Customer.create customerNumber firstName))
let addOrder orderNumber name = Data.updateOrders (snoc (Order.create orderNumber name))
let addInvoice id amount name = Data.updateInvoices (snoc (Invoice.create id amount name))
which cuts a little bit of boilerplate I guess? You could slightly update that to use lenses from F#+:
module Data =
let _customers f d = f d.Customers <&> fun x -> { d with Customers = x }
let _orders f d = f d.Orders <&> fun x -> { d with Orders = x }
...
let snoc x xs = xs @ [x]
let addCustomer customerNumber firstName = over Data._customers (snoc (Customer.create customerNumber firstName))
let addOrder orderNumber name = over Data._orders (snoc (Order.create orderNumber name))
let addInvoice id amount name = over Data._invoices (snoc (Invoice.create id amount name))
which is at least a bit more standardized of a pattern than the first one, though requires anyone working with it to have a basic familiarity with lenses.
I can’t think of any other ways to shorten it.
Thank you for taking the time to provide some ideas.