# Trying to do Type-Driven Development in F#

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:

1. Get report templates. In this step I query a DB and get some templates for reports
2. Update data that the reports are working on. In this step I query some banking services and save our data on our DB
3. 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
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
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.DateFrom) claimantTemplates.ReportTemplates |> List.min
let maxDateWithNone = List.map (fun x -> x.DateTo) claimantTemplates.ReportTemplates |> List.max
let maxDateWithoutNone = List.map (fun x -> x.DateTo) claimantTemplates.ReportTemplates |> getValuesInListOfOptions |> List.max

match maxDateWithNone with
| None -> updateClaimantData minDate DateTime.Today claimantTemplates.BankingServices
| _ -> updateClaimantData minDate maxDateWithoutNone claimantTemplates.BankingServices

List.map (fun x -> x.Name) claimantTemplates.ReportTemplates

let getClaimantTemplates data createClaimantTemplate : ClaimantTemplates list =
data |> List.map createClaimantTemplate

//The root of the program
let generateReports (getClaimantTemplates: unit -> ClaimantTemplates list) (updateData: ClaimantTemplates -> ReportTemplateName list) (createReport: ReportTemplateName -> unit) =
getClaimantTemplates () |> List.map updateData |> List.concat |> List.map createReport |> ignore


I'm at the point where the updateClaimantData and getClaimantTemplates require data access and the createReport function that generateReports needs is also a data access function.

I was hoping to get some criticism to see if I'm on the right track. I'm both new to the language and functional languages as well.

• The desire to improve code is implied for all questions on this site. Question titles should reflect the purpose of the code, not how you wish to have it reworked. See How to Ask.
– Jamal
Oct 14 '15 at 17:01

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.