patternMinor
Trying to do Type-Driven Development in F#
Viewed 0 times
typetryingdevelopmentdriven
Problem
I've been wanting to try out F# for some real world programming so I decided to try rewriting a program that is being used at work.
It can be reduced to a few steps:
In this step I query a DB and get some templates for reports
In this step I query some banking services and save our data on our DB
In this step I call a stored procedure that generates a new report
I'm trying to do this outside in and have been using Mark Seemann's blog and Scott Wlaschin's guide as a guide and this is what I've got so far:
```
module Helpers =
let getValuesInListOfOptions list =
List.choose (fun x ->
match x with
| Some value -> Some value
| _ -> None ) list
module PaymentVelocityReports =
open System;
open Helpers;
type ReportTemplateName = string
type ReportTemplate = {
Id: int
GroupId: int
ReportOwnerSSN: string
Name: ReportTemplateName
Description: string
Enabled: bool
DayOfMonthToRun: int
DateFrom: DateTime
DateTo: DateTime option
UpdateData: bool}
type Claimant = {
Id: decimal
Ssn: string
}
type BankingService = {
Id: decimal
ClaimantId: decimal
Bank: string
Username: string
Password: string
Enabled: bool
}
type ClaimantTemplates ={
ReportTemplates: ReportTemplate list
Claimant: Claimant
BankingServices: BankingService list
}
let updateClaimantData saveNewGiros saveNewPayments (dateFrom: DateTime) (dateTo: DateTime) (bankingServices: BankingService list) =
List.iter (fun x -> saveNewGiros dateFrom dateTo x) bankingServices
List.iter (fun x -> saveNewPayments dateFrom dateTo x) bankingServices
let updateData updateClaimantData (claimantTemplates: ClaimantTemplates) : ReportTemplateName list =
if List.exists (fun x -> x.UpdateData) claimantTemplates.ReportTemplates then
let minDate = List.map (fun x -> x.Da
It can be reduced to a few steps:
- Get report templates.
In this step I query a DB and get some templates for reports
- Update data that the reports are working on.
In this step I query some banking services and save our data on our DB
- Generate new reports.
In this step I call a stored procedure that generates a new report
I'm trying to do this outside in and have been using Mark Seemann's blog and Scott Wlaschin's guide as a guide and this is what I've got so far:
```
module Helpers =
let getValuesInListOfOptions list =
List.choose (fun x ->
match x with
| Some value -> Some value
| _ -> None ) list
module PaymentVelocityReports =
open System;
open Helpers;
type ReportTemplateName = string
type ReportTemplate = {
Id: int
GroupId: int
ReportOwnerSSN: string
Name: ReportTemplateName
Description: string
Enabled: bool
DayOfMonthToRun: int
DateFrom: DateTime
DateTo: DateTime option
UpdateData: bool}
type Claimant = {
Id: decimal
Ssn: string
}
type BankingService = {
Id: decimal
ClaimantId: decimal
Bank: string
Username: string
Password: string
Enabled: bool
}
type ClaimantTemplates ={
ReportTemplates: ReportTemplate list
Claimant: Claimant
BankingServices: BankingService list
}
let updateClaimantData saveNewGiros saveNewPayments (dateFrom: DateTime) (dateTo: DateTime) (bankingServices: BankingService list) =
List.iter (fun x -> saveNewGiros dateFrom dateTo x) bankingServices
List.iter (fun x -> saveNewPayments dateFrom dateTo x) bankingServices
let updateData updateClaimantData (claimantTemplates: ClaimantTemplates) : ReportTemplateName list =
if List.exists (fun x -> x.UpdateData) claimantTemplates.ReportTemplates then
let minDate = List.map (fun x -> x.Da
Solution
From a cursory glance, this looks like a good start, but I haven't made a full exegesis of the code.
A couple of observations:
The
It seems odd to me that the function with the comment The root of the program is still a higher-order function defined in the same module as all the other functions. I'd expect the root of the program to be something akin to a
A couple of observations:
The
getValuesInListOfOptions function seems redundant. AFAICT, you can rewrite the function as List.choose id list, in which case you could inline that expression and remove the function.It seems odd to me that the function with the comment The root of the program is still a higher-order function defined in the same module as all the other functions. I'd expect the root of the program to be something akin to a
main function, that only takes command-line string arguments as input, if it takes any arguments at all.Context
StackExchange Code Review Q#107546, answer score: 2
Revisions (0)
No revisions yet.