Skip to content

Instantly share code, notes, and snippets.

@Gab-km
Created July 13, 2012 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gab-km/3108217 to your computer and use it in GitHub Desktop.
Save Gab-km/3108217 to your computer and use it in GitHub Desktop.
「できる!コンピュテーション式」のサンプルコード vol.1
type BindBuilder () =
member self.Bind (x, f) = f x
member self.Return x = x
let bind = BindBuilder()
bind {
let! x = 1
let! y = 2
return x + y
} |> printfn "%d" (* #=> 3 *)
bind {
do! printf "%s" "F#!"
printf "%s" "F#!"
} (* #=> F#!F#! *)
type CombineBuilder(plus : 'a -> 'a -> 'a, g : 'a -> 'a) =
member self.Combine (x, y) = plus x y
member self.Return x = x
member self.Delay f = f () |> g
let combine = CombineBuilder((fun x y -> x + y), (fun x -> x*2))
combine {
return 1
return 2
return 3
} |> printfn "%d" (* #=> 34 *)
combine.Delay(fun () ->
combine.Combine(
combine.Return(1),
combine.Delay(fun () ->
combine.Combine(
combine.Return(2),
combine.Delay(fun () ->
combine.Return(3)
)
)
)
)
)
comp.Run(comp.Delay(fun () ->
comp.Bind(MyType 3, fun x ->
comp.Bind(MyType 2, fun y ->
comp.Return(x + y)
)
)
))
type MyType<'a> = MyType of 'a
type MyBuilder() =
member self.Bind (x, f) =
match x with
| MyType (y) = f y
member self.Return (x) = MyType(x)
let comp = MyBuilder()
comp {
let! x = MyType 3
let! y = MyType 2
return x + y
} |> printfn "%A" (* MyType 5 *)
type DelayBuilder (g : 'a -> 'a) =
new() = new DelayBuilder(id)
member self.Bind (x, f) = f x
member self.Delay f = f () |> g
member self.Return x = x
let delay = DelayBuilder(fun x -> x*2)
delay {
let! x = 3
let! y = 4
return x + y (* この時点では 7 *)
} |> printfn "%d" (* #=> 14 *)
type ForBuilder() =
member self.For (xs, f) = Seq.map f xs
member self.Yield x = x
let forb = ForBuilder()
forb {
for x in [1..5] do yield x*2
} |> printfn "%A" (* #=> seq [2; 4; 6; 8; ...] *)
type SumBuilder() =
member self.For (xs, f) = Seq.map f xs |> Seq.sum
member self.Yield x = x
let sumb = SumBuilder()
sumb {
for x in [1..5] do yield x
} |> printfn "%d" (* #=> 15 *)
type ReturnType<'a> = ReturnType of 'a
type ReturnBuilder(g : 'a -> 'a) =
member self.Bind (x, f) =
match x with
| ReturnType y -> f y
member self.ReturnFrom x = g x
let returnfrom = ReturnBuilder(fun x -> x*3)
returnfrom {
let! x = ReturnType 2
let! y = ReturnType 5
return! x * y (* この時点では 10 *)
} |> printfn "%d" (* #=> 30 *)
type ReturnType<'a> = ReturnType of 'a
type ReturnBuilder(g : 'a -> 'a) =
member self.Bind (x, f) =
match x with
| ReturnType y -> f y
member self.Return x = ReturnType (g x)
let returnb = ReturnBuilder(fun x -> x*3)
let ret = ReturnType
returnb {
let! x = ret 2
let! y = ret 1
return x - y (* この時点では 1 *)
} |> printfn "%A" (* #=> ReturnType 3 *)
type RunType<'a> = RunType of 'a
type RunBuilder() =
member self.Bind (x, f) =
match x with
| RunType(y) -> f y
member self.Return x = RunType x
member self.Run x =
match x with
| RunType(y) -> y
let run = RunBuilder()
let get = RunType
run {
let! x = get 3
let! y = get 5
return x + y (* この時点では RunType 8 *)
} |> printfn "%A" (* #=> 8 *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment