Skip to content

Instantly share code, notes, and snippets.

@Gab-km
Last active October 7, 2015 04:48
Show Gist options
  • Select an option

  • Save Gab-km/3108219 to your computer and use it in GitHub Desktop.

Select an option

Save Gab-km/3108219 to your computer and use it in GitHub Desktop.
「できる!コンピュテーション式」のサンプルコード vol.2
type TFBuilder() =
member self.TryFinally (x, f) =
f ()
x
member self.Delay f = f ()
member self.Bind (x, f) = f x
member self.Return x = x
let tfb = TFBuilder()
tfb {
let! x = 3
let! y = 4
try
return x + y
finally
printfn "%s" "F#!F#!"
} |> printfn "%d"
(* #=> F#!F#!
7 *)
type Doing =
| Done of int
| Undone of System.Exception
type TWBuilder () =
member self.TryWith (x, f) =
match x with
| Done(x) -> x
| Undone(exn) -> f (exn); 0
member self.Delay f = try Done(f ()) with exn -> Undone(exn)
member self.Bind (x, f) = f x
member self.Return x = x
member self.Zero () = self.Return ()
let twb = TWBuilder()
twb {
let! x = 6
let! y = 2
try
return x / y
with
| exn -> printfn "%A" exn
} |> printfn "%A"
(* #=> Done 3 *)
twb {
let! x = 3
let! y = 0
try
return x / y
with
| exn -> printfn "%A" exn
} |> printfn "%A"
(* #=> System.DivideByZeroException: 0 で除算しようとしました。
** スタックトレース略 **
Done 0 *)
open System
type UsingType(data) =
member self.Data
with get () = data
member self.Substitute (other : UsingType) =
new UsingType(String.Format(self.Data, other.Data))
interface IDisposable with
member self.Dispose() = printfn "Dispose!:%A" self.Data
type UsingBuilder() =
member self.Using (x, f) =
use y = x
f y
member self.Return x = x
let usingb = UsingBuilder()
let using x = new UsingType(x)
usingb {
use x = using "{0}#!{0}#!"
use y = using "F"
return x.Substitute(y)
} |> fun z -> printfn "%s" z.Data
(* #=> Dispose!:"F"
Dispose!:"{0}#!{0}#!"
F#!F#! *)
type WhileBuilder(zero, plus) =
member self.Delay f = f
member self.While(f, x) =
if f() then plus (x()) (self.While(f, x))
else zero
member self.Yield x = x
member self.Combine (x, y) = x + y()
member self.Zero () = zero
member self.Run f = f ()
let whileb = WhileBuilder(0, (+))
whileb {
let x = ref 0
while !x < 5 do
yield !x
x := !x + 1
} |> printfn "%A" (* #=> 10 *)
type YieldType<'a> = YieldType of 'a
type YieldFromBuilder() =
member self.Bind (x, f) =
match x with
| YieldType(y) -> f y
member self.YieldFrom x = x
let yieldfb = YieldFromBuilder()
yieldfb {
let! x = YieldType(3)
let! y = YieldType(2)
yield! x - y
} |> printfn "%d" (* #=> 1 *)
type YieldType<'a> = YieldType of 'a
type YieldBuilder() =
member self.Bind (x, f) =
match x with
| YieldType(y) -> f y
member self.Yield x = YieldType x
let yieldb = YieldBuilder()
yieldb {
let! x = YieldType(3)
let! y = YieldType(2)
yield x - y
} |> printfn "%A" (* #=> YieldType 1 *)
type ZeroBuilder() =
member self.Zero () = 0
let zero = ZeroBuilder()
zero {
()
} |> printfn "%d" (* #=> 0 *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment