Skip to content

Instantly share code, notes, and snippets.

@sayurin
Created December 26, 2016 09:34
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 sayurin/e326a8084f625bf5319f67c66c7c525b to your computer and use it in GitHub Desktop.
Save sayurin/e326a8084f625bf5319f67c66c7c525b to your computer and use it in GitHub Desktop.
dict関数のコンピュテーション式バージョン。一旦 seq<key, value> 型に変換せずに直接 Dictionay<key, value> を作成する。
open System
open System.Collections.Generic
type State<'Key, 'Value when 'Key : equality> =
| Dict of Dictionary<'Key, 'Value>
| Item of 'Key * 'Value
| Empty
type DictBuilder<'Key, 'Value when 'Key : equality> (equalityComparer : _ IEqualityComparer) =
let create () = Dictionary<'Key, 'Value> equalityComparer
let dict f = let dic = create () in f dic; Dict dic
let add (dic : Dictionary<_, _>) state =
match state with
| Dict dic2 -> for KeyValue(key, value) in dic2 do dic.Add(key, value)
| Item(key, value) -> dic.Add(key, value)
| Empty -> ()
member __.Zero() = Empty
member __.Yield(key, value) = Item (key, value)
member __.YieldFrom(seq : _ seq) = dict <| fun dic ->
match box seq with
| :? array<'Key * 'Value> as array -> Array.iter dic.Add array
| :? list<'Key * 'Value> as list -> List.iter dic.Add list
| _ -> Seq.iter dic.Add seq
member __.Using(disposable : IDisposable, f) = try f disposable finally match box disposable with null -> () | _ -> disposable.Dispose()
member __.Combine(state, rest) =
match state, rest () with
| Empty, state
| state, Empty -> state
| Dict dic, Item(key, value)
| Item(key, value), Dict dic -> dic.Add(key, value); Dict dic
| Dict dic1, Dict dic2 -> for KeyValue(key, value) in dic2 do dic1.Add(key, value) done; state
| Item(key1, value1), Item(key2, value2) -> dict <| fun dic -> dic.Add(key1, value1); dic.Add(key2, value2)
member __.TryWith(f, h) = try f () with e -> h e
member __.TryFinally(f, g) = try f () finally g ()
member __.While(guard, f) = dict <| fun dic -> while guard () do add dic <| f ()
member __.For(seq : _ seq, f) = dict <| fun dic ->
match box seq with
| :? array<_> as array -> for item in array do add dic <| f item
| :? list<_> as list -> for item in list do add dic <| f item
| _ -> for item in seq do add dic <| f item
member __.Delay(f) = f
member __.Run(f) =
match f () with
| Dict dic -> dic
| Item(key, value) -> let dic = create () in dic.Add(key, value); dic
| Empty -> create ()
let dict = DictBuilder null
let idict = DictBuilder StringComparer.InvariantCultureIgnoreCase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment