Skip to content

Instantly share code, notes, and snippets.

@adacola
Last active December 19, 2015 13:33
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 adacola/e6d5acfbde0b5d042047 to your computer and use it in GitHub Desktop.
Save adacola/e6d5acfbde0b5d042047 to your computer and use it in GitHub Desktop.
The Lazy.Force Awakens
let lazy1 = lazy (printfn "hoge"; 1)
// val lazy1 : Lazy<int> = 値は作成されていません。
// The Force Awakens
lazy1.Force()
// hoge
// val it : int = 1
lazy1.Force()
// val it : int = 1
let func1 = fun () -> printfn "fuga"; 2
// val func1 : unit -> int
func1()
// fuga
// val it : int = 2
func1()
// fuga
// val it : int = 2
let mutable s = "hoge"
let lazy2 = lazy (s)
let func2 = fun () -> s
lazy2.Force()
// val it : string = "hoge"
func2()
// val it : string = "hoge"
s <- "fuga"
lazy2.Force()
// val it : string = "hoge"
func2()
// val it : string = "fuga"
// unit -> 'a を Lazy<'a> に変換する関数
let lazy3 = func1 |> Lazy.Create
// val lazy3 : Lazy<int> = 値は作成されていません。
lazy3.Force()
// fuga
// val it : int = 2
lazy3.Force()
// val it : int = 2
// System.Lazyクラスのコンストラクタ呼び出し。F#4以降は関数のように扱える
let lazy3' = func1 |> Lazy
// Lazy<'a> を unit -> 'a に(シグネチャだけ)変換する方法
let func3 = lazy1.Force
// val func3 : (unit -> int)
func3()
// hoge
// val it : int = 1
func3()
// val it : int = 1
// lazy内で例外が出た場合は例外がキャッシュされて、評価のたびにキャッシュされた例外が投げられる
let mutable x = "Jedi"
let f() = if x = "Jedi" then 0 else failwithf "oops! : %s" x
let lazyDarkSide = f |> Lazy
x <- "Darth Vador"
lazyDarkSide.Force()
(*
System.Exception: oops! : Darth Vador
> 場所 FSI_0233.f@65-11.Invoke(String message) 場所 force.fsx:行 65
場所 System.Lazy`1.CreateValue()
場所 System.Lazy`1.LazyInitValue()
場所 <StartupCode$FSI_0234>.$FSI_0234.main@() 場所 force.fsx:行 69
エラーのため停止しました
*)
x <- "Jedi"
lazyDarkSide.Force()
(*
> System.Exception: oops! : Darth Vador
場所 FSI_0233.f@65-11.Invoke(String message) 場所 force.fsx:行 65
場所 System.Lazy`1.CreateValue()
--- 直前に例外がスローされた場所からのスタック トレースの終わり ---
場所 System.Lazy`1.get_Value()
場所 <StartupCode$FSI_0236>.$FSI_0236.main@() 場所 force.fsx:行 80
エラーのため停止しました
*)
x <- "Anakin Skywalker"
lazyDarkSide.Force()
(*
System.Exception: oops! : Darth Vador
> 場所 FSI_0233.f@65-11.Invoke(String message) 場所 force.fsx:行 65
場所 System.Lazy`1.CreateValue()
--- 直前に例外がスローされた場所からのスタック トレースの終わり ---
場所 System.Lazy`1.get_Value()
場所 <StartupCode$FSI_0240>.$FSI_0240.main@() 場所 force.fsx:行 92
エラーのため停止しました
*)
// Lazyのコンストラクタの別バージョン。シングルスレッド用
let lazy4 = Lazy((fun () -> printfn "piyo"; 3), false)
// Lazyのコンストラクタの別バージョン。初期化処理は同時に行われるがキャッシュは1つだけ作成される
let lazy5 = Lazy((fun () -> printfn "foo"; 4), System.Threading.LazyThreadSafetyMode.PublicationOnly)
// Lazyのコンストラクタの別バージョン。指定した型のデフォルトコンストラクタを遅延呼び出しする
let lazyDefaultInt = Lazy<int>()
lazy4.IsValueCreated
// val it : bool = false
// Force()を使わなくてもValueプロパティで評価できる
lazy4.Value
// piyo
// val it : int = 3
lazy4.Value
// val it : int = 3
lazy4.IsValueCreated
// val it : bool = true
// Force()を使わなくてもパターンマッチで評価できる
lazy5 |> fun (Lazy x) -> x
// foo
// val it : int = 4
let lazy6 = Lazy(f, System.Threading.LazyThreadSafetyMode.PublicationOnly)
x <- "Darth Vador"
lazy6.Force()
(*
System.Exception: oops! : Darth Vador
> 場所 FSI_0233.f@65-11.Invoke(String message) 場所 force.fsx:行 65
場所 System.Lazy`1.CreateValue()
場所 System.Lazy`1.LazyInitValue()
場所 <StartupCode$FSI_0243>.$FSI_0243.main@() 場所 force.fsx:行 126
エラーのため停止しました
*)
x <- "Jedi"
lazy6.Force()
// val it : int = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment