Last active
August 25, 2017 01:43
-
-
Save panesofglass/fd2215da0eef4456a183bd693819c694 to your computer and use it in GitHub Desktop.
inference and builders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Op = | |
| Add | |
| Multiply | |
static member TryParse input = | |
match input with | |
| "add" -> Some Add | |
| "multiply" -> Some Multiply | |
| _ -> None | |
type Command<'a> = | |
| Command of ('a * 'a -> 'a) | |
module Command = | |
type Defaults = | |
| Defaults | |
static member Command (command:Command<_>) = | |
command | |
static member inline Command op = | |
Command(fun (x,y) -> match op with Add -> x + y | Multiply -> x * y) | |
static member inline Command op = | |
match Op.TryParse op with | |
| Some op -> Defaults.Command op | |
| None -> failwithf "invalid operator %s" op | |
let inline defaults (a: ^a, _: ^b) = | |
((^a or ^b) : (static member Command: ^a -> Command<_>) a) | |
let inline infer (x: 'a) = | |
defaults (x, Defaults) | |
let (Command f) = Command.infer Add | |
f(1,2) | |
let (Command f') = Command.infer "multiply" | |
f'(2,3) | |
module Workflow = | |
[<Sealed>] | |
type Builder() = | |
member inline this.Bind(op, f) = | |
let (Command c) = Command.infer op in f c | |
member inline this.For(op, f) = | |
let (Command c) = Command.infer op in f c | |
[<CustomOperation("apply", MaintainsVariableSpaceUsingBind=true)>] | |
member inline this.Apply(f, args) = f args | |
member this.Yield(x) = x | |
member this.Return(x) = x | |
let b = Builder() | |
let inline test op x y = | |
b { | |
let! f = op | |
return f(x,y) | |
} | |
let inline test' op x y = | |
b { for f in op do apply (x,y) } | |
let inline test'' op x y = | |
b { | |
let! f = op | |
// weird ... applies f | |
apply (x,y) | |
} | |
Workflow.test "add" 1 2 | |
Workflow.test' Multiply 1. 2. | |
Workflow.test'' (Command(fun (x,y) -> x / y)) 13I 2I |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment