Last active
July 27, 2020 21:05
-
-
Save Szer/60f1a85b59ca539849ecf235087d0bcd 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
type IBuilderResult = interface end | |
type ICombinable = inherit IBuilderResult | |
type INonCombinable = inherit IBuilderResult | |
type First = | |
| Payload of int | |
| Nested of ICombinable | |
interface ICombinable | |
type Second = | |
| Payload of string | |
interface INonCombinable | |
and AllBuilder() = | |
member __.Yield (xs: First list) = [ for x in xs -> x :> ICombinable] | |
member __.Yield (xs: Second list) = [ for x in xs -> x :> INonCombinable] | |
member __.Combine (x: ICombinable list, y: INonCombinable list) = | |
Seq.cast<IBuilderResult> x | |
|> Seq.append (Seq.cast<IBuilderResult> y) | |
|> Seq.toList | |
member __.Combine (x: ICombinable list, y: ICombinable list) = x @ y | |
member __.Combine (x: ICombinable list, y: IBuilderResult list) = | |
y @ (Seq.cast<IBuilderResult> x |> Seq.toList) | |
member __.Delay f = f() | |
member __.Zero() = [] | |
and FirstBuilder() = | |
member __.Yield (x: int) = [First.Payload x] | |
member __.Yield (x: ICombinable) = [First.Nested x] | |
member __.Combine (x, y) = x @ y | |
member __.Delay f = f() | |
member __.Zero() = [] | |
and SecondBuilder() = | |
member __.Yield (x: string) = [Second.Payload x] | |
member __.Combine (x, y) = x @ y | |
member __.Delay f = f() | |
member __.Zero() = [] | |
let all = AllBuilder() | |
let first = FirstBuilder() | |
let second = SecondBuilder() | |
let a = first { 1 } | |
let b = second { "2" } | |
// allowed to combine with non-combinable once | |
// IBuilderResult list | |
let example = | |
all { | |
a | |
b | |
//b | |
} | |
// allowed to combine combinable how many times you want | |
// ICombinable list | |
let example2 = | |
all { | |
a | |
a | |
a | |
a | |
} | |
// not allowed to combine with noncombinable | |
// INonCombinable list | |
let example3 = | |
all { | |
b | |
// not allowed to place second b here | |
//b | |
} | |
// allowd to combine combinable how many times you want and end with one non-combinable | |
// IBuilderResult list | |
let example4 = | |
all { | |
a | |
a | |
a | |
b | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment