0 people like it.

Splitting sequences of arbitrary unions

A small snippet that groups sequences of arbitrary unions by branch type.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
open Microsoft.FSharp.Reflection

let split (unions : 'T seq) =
    let reader = FSharpValue.PreComputeUnionTagReader typeof<'T>
    let map = unions    |> Seq.groupBy reader 
                        |> Seq.map (fun (x,y) -> x, Seq.toList y)
                        |> Map.ofSeq
    //fun (x : 'T) -> map.TryFind (reader x)
    map

// example

type Foo = A | B | C | D | E

let map = [ A ; B ; C ; D ; A ; A ; B ; C ; D ; B ; B ; A ] |> split

if map.ContainsKey 0 && not <| map.ContainsKey 4 then 
    printfn "the sequence contains an A but not an E."
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
val split : unions:seq<'T> -> Map<int,'T list>

Full name: Script.split
val unions : seq<'T>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val reader : (obj -> int)
type FSharpValue =
  static member GetExceptionFields : exn:obj * ?bindingFlags:BindingFlags -> obj []
  static member GetRecordField : record:obj * info:PropertyInfo -> obj
  static member GetRecordFields : record:obj * ?bindingFlags:BindingFlags -> obj []
  static member GetTupleField : tuple:obj * index:int -> obj
  static member GetTupleFields : tuple:obj -> obj []
  static member GetUnionFields : value:obj * unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo * obj []
  static member MakeFunction : functionType:Type * implementation:(obj -> obj) -> obj
  static member MakeRecord : recordType:Type * values:obj [] * ?bindingFlags:BindingFlags -> obj
  static member MakeTuple : tupleElements:obj [] * tupleType:Type -> obj
  static member MakeUnion : unionCase:UnionCaseInfo * args:obj [] * ?bindingFlags:BindingFlags -> obj
  ...

Full name: Microsoft.FSharp.Reflection.FSharpValue
static member FSharpValue.PreComputeUnionTagReader : unionType:System.Type * ?allowAccessToPrivateRepresentation:bool -> (obj -> int)
static member FSharpValue.PreComputeUnionTagReader : unionType:System.Type * ?bindingFlags:System.Reflection.BindingFlags -> (obj -> int)
val typeof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val map : Map<int,'T list>
module Seq

from Microsoft.FSharp.Collections
val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> (requires equality)

Full name: Microsoft.FSharp.Collections.Seq.groupBy
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val x : int
val y : seq<'T>
val toList : source:seq<'T> -> 'T list

Full name: Microsoft.FSharp.Collections.Seq.toList
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
  interface IEnumerable
  interface IComparable
  interface IEnumerable<KeyValuePair<'Key,'Value>>
  interface ICollection<KeyValuePair<'Key,'Value>>
  interface IDictionary<'Key,'Value>
  new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
  member Add : key:'Key * value:'Value -> Map<'Key,'Value>
  member ContainsKey : key:'Key -> bool
  override Equals : obj -> bool
  member Remove : key:'Key -> Map<'Key,'Value>
  ...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofSeq : elements:seq<'Key * 'T> -> Map<'Key,'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.ofSeq
type Foo =
  | A
  | B
  | C
  | D
  | E

Full name: Script.Foo
union case Foo.A: Foo
union case Foo.B: Foo
union case Foo.C: Foo
union case Foo.D: Foo
union case Foo.E: Foo
val map : Map<int,Foo list>

Full name: Script.map
member Map.ContainsKey : key:'Key -> bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn

More information

Link:http://fssnip.net/gg
Posted:4 years ago
Author:Eirik Tsarpalis
Tags: discriminated unions , reflection