Skip to content

Instantly share code, notes, and snippets.

@Szer
Last active July 27, 2020 21:05
Show Gist options
  • Save Szer/60f1a85b59ca539849ecf235087d0bcd to your computer and use it in GitHub Desktop.
Save Szer/60f1a85b59ca539849ecf235087d0bcd to your computer and use it in GitHub Desktop.
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