open System type Logger = { Log : string -> unit } type HelloService = { SayHelloTo : string -> unit } // This is the constructor of a logger that adds a timestamp in the specified // format to each log message it writes. let dateTimeLogger (dateFormat : string) = { Log = fun msg -> let timestamp = DateTime.Now.ToString dateFormat printfn "[%s]: %s" timestamp msg } let logger = dateTimeLogger "yyyy-MM-dd hh:mm:ss" // This implementation of Logger ignores all messages let noopLogger = { Log = ignore } let doSomething logger = logger.Log "Starting to do something" let x = 1 + 1 sprintf "Did something! Result: %d" x |> logger.Log // Implementations can be injected to application code doSomething logger doSomething noopLogger // Implement HelloService. Our implementation depends on a Logger to write // messages to. let helloService logger = { SayHelloTo = fun user -> sprintf "Saying hi to %s" user |> logger.Log printfn "Hi %s!" user logger.Log "Operation complete" } // Create an instance of helloService. // // We don't want to do anything with the messages so we discard them by using // injecting noopLogger as the implementation of Logger. let instance = helloService noopLogger instance.SayHelloTo "John"