Skip to content

Instantly share code, notes, and snippets.

@BashkaMen
Created October 22, 2020 21:35
Show Gist options
  • Save BashkaMen/d6b74cc7faecf8585606040ad3ae5969 to your computer and use it in GitHub Desktop.
Save BashkaMen/d6b74cc7faecf8585606040ad3ae5969 to your computer and use it in GitHub Desktop.
// Learn more about F# at http://fsharp.org
open System
open System.Threading.Tasks
let ( ^ ) f x = f x
type IStore =
abstract member Save: 'T -> Guid
type ILogger =
abstract member Log: string -> unit
type AppConfig = {
AppName: string
}
type Dependencies = {
Logger: ILogger
Store: IStore
Config: AppConfig
}
type Env<'a> = (Dependencies -> 'a)
let bind (f: 'a -> Env<'b>) (v: Env<'a>) : Env<'b> =
fun deps -> f (v deps) deps
let map (f: 'a -> 'b) (v: Env<'a>) : Env<'b> =
fun deps -> f (v deps)
let ( >>= ) x f = bind f x
let envPure (v: 'a): Env<'a> = fun _ -> v
type EnvBuilder() =
member this.Return v = envPure v
member this.Bind(env, f) = bind f env
member this.Zero() = envPure ()
let env = EnvBuilder()
let store = {
new IStore with
member _.Save a = Guid.NewGuid()
}
let logger = {
new ILogger with
member _.Log message =
printfn "%s" message
}
module Logger =
let log message deps =
let name = deps.Config.AppName
deps.Logger.Log ^ sprintf "(%s) %s" name message
module Store =
let save item deps =
Logger.log "Save item..." deps
deps.Store.Save item
module Run =
let mailEnv = env {
do! Logger.log "hello from env monad"
do! Logger.log "step 1 from env monad"
let! result = Store.save "USER DATA"
do! Logger.log ^ sprintf "item save with %A id" result
return 0
}
[<EntryPoint>]
let main argv =
let deps = {
Store = store
Logger = logger
Config = { AppName = "Monad test" }
}
Run.mailEnv deps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment