Skip to content

Instantly share code, notes, and snippets.

@bryanedds
Last active August 13, 2016 11:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bryanedds/3f26a256a600a581d915 to your computer and use it in GitHub Desktop.
Save bryanedds/3f26a256a600a581d915 to your computer and use it in GitHub Desktop.
open System
open FSharpx.Reader
[<AutoOpen>]
module LoggerModule =
/// A fake logger type.
type Logger =
private { __ : unit }
[<RequireQualifiedAccess; CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Logger =
let info (_ : string) (_ : Logger) = ()
let warn (_ : string) (_ : Logger) = ()
let error (_ : string) (_ : Logger) = ()
let make () = { __ = () }
[<AutoOpen>]
module DatabaseConnectionModule =
/// A fake database connection type.
type DatabaseConnection =
private { __ : unit }
[<RequireQualifiedAccess; CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module DatabaseConnection =
let getName (_ : DatabaseConnection) = "MyDatabase"
let getValue (_ : DatabaseConnection) = 10
let make (_ : string) = { __ = () }
[<AutoOpen>]
module FrobServiceModule =
/// A service that can frobnicate at the given sanitation capacity and finalization rate.
type FrobService =
private
{ SanitationCapacity : int
FinalizationRate : int
Logger : Logger
Database : DatabaseConnection }
[<RequireQualifiedAccess; CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module FrobService =
let private queryFrobData frobService =
DatabaseConnection.getValue frobService.Database
let private trySanitizeFrobData frobData frobservice =
Some <| max frobData frobservice.SanitationCapacity
let private finalizeFrobData frobData frobService =
frobData * frobService.FinalizationRate
/// Attempt to frobnicate.
let tryFrobnicate frobService =
// query frob data
Logger.info ("Querying frob data from source " + DatabaseConnection.getName frobService.Database) frobService.Logger
let frobData = queryFrobData frobService
// attempt to sanitize frob data
match trySanitizeFrobData frobData frobService with
| Some frobData ->
// finalize frob data
let frobData = finalizeFrobData frobData frobService
Some frobData
// warn of failure!
| None ->
Logger.warn ("Failed to sanitize frob data " + string frobData) frobService.Logger
None
/// Make a frob service.
let make sanitationCapacity finalizationRate logger database =
{ SanitationCapacity = sanitationCapacity; FinalizationRate = finalizationRate; Logger = logger; Database = database }
/// Program entry point.
let [<EntryPoint>] main _ =
// build frob service
let logger = Logger.make ()
let database = DatabaseConnection.make "DB=MyDatabase;User=Me;Password=12345"
let frobService = FrobService.make 20 60 logger database
// attempt to frobnicate using the Reader monad
let frobber = reader { return! FrobService.tryFrobnicate }
match Reader.ask frobber frobService with
| Some frobData -> printfn "Frobnication result: %i frobs." frobData
| None -> Logger.error "Frobnication failure!" logger
// return an integer exit code
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment