Created
February 18, 2020 13:47
-
-
Save dsyme/5dd08c84ad7bdee3ad556af742172eda to your computer and use it in GitHub Desktop.
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
[<AbstractClass>] | |
type Node<'T>() = | |
abstract Value: 'T | |
abstract Name: string | |
let TipNode<'T>(name:string, value: 'T) = | |
{ new Node<'T>() with | |
override _.Value = value | |
override _.Name = name | |
override _.ToString() = name } | |
let ZipNode<'T1, 'T2>(node1: Node<'T1>, node2: Node<'T2>) = | |
{ new Node<'T1 * 'T2>() with | |
override _.Value = (node1.Value, node2.Value) | |
override _.Name = node1.Name + "," + node2.Name | |
override x.ToString() = x.Name } | |
let MapNode<'T, 'U>(node: Node<'T>, f: 'T -> 'U) = | |
{ new Node<'U>() with | |
override _.Value = f node.Value | |
override _.Name = node.Name | |
override x.ToString() = x.Name } | |
let NamePrefixNode<'T>(prefix:string, node: Node<'T>) = | |
{ new Node<'T>() with | |
override _.Value = node.Value | |
override _.Name = prefix + "/" + node.Name | |
override x.ToString() = x.Name } | |
let BindNode<'T, 'U>(node: Node<'T>, f: 'T -> Node<'U>) = | |
{ new Node<'U>() with | |
override _.Value = (f node.Value).Value | |
override _.Name = node.Name | |
override x.ToString() = x.Name } | |
type NodeBuilder() = | |
member _.Bind(x: Node<'T1>, f: 'T1 -> Node<'T2>) : Node<'T2> = BindNode (x, f) | |
member _.BindReturn(x: Node<'T1>, f: 'T1 -> 'T2) : Node<'T2> = MapNode (x, f) | |
member _.MergeSources(x1: Node<'T1>, x2: Node<'T2>) = ZipNode(x1, x2) | |
member _.Return(x: 'T) : Node<'T> = TipNode("ret", x) | |
[<CustomOperation("prefix", MaintainsVariableSpaceUsingBind=true) >] | |
member _.Prefix(x: Node<'T>, prefix: string) = NamePrefixNode(prefix, x) | |
let node = NodeBuilder() | |
let tip nm v = TipNode(nm, v) | |
let test1() = | |
node { | |
let! v1 = tip "a" 3 | |
and! v2 = tip "b" 4 | |
and! v3 = tip "c" 5 | |
prefix "test1" | |
return v1 + v2 + v3 | |
} | |
test1() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment