3 people like it.
Like the snippet!
Inverse map for parsing DU cases
Neat trick to improve safety
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
open FSharp.Reflection
type Keyword =
| FOO
| BAR
| BAZ
| BLAH
let inverseMap (print: 'T -> string) (cases: 'T seq) =
let lookup =
cases
|> Seq.map (fun case -> print case, case)
|> Map.ofSeq
fun (line: string) -> Map.tryFind line lookup
let cases<'T> =
FSharpType.GetUnionCases(typeof<'T>)
|> Seq.map (fun c -> FSharpValue.MakeUnion(c, Array.empty) :?> 'T)
let matchKeyword: string -> Keyword option =
inverseMap string cases<Keyword>
printfn "%A" (matchKeyword "BAR")
// Some BAR
printfn "%A" (matchKeyword "NOP")
// None
|
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
type Keyword =
| FOO
| BAR
| BAZ
| BLAH
union case Keyword.FOO: Keyword
union case Keyword.BAR: Keyword
union case Keyword.BAZ: Keyword
union case Keyword.BLAH: Keyword
val inverseMap : print:('T -> string) -> cases:seq<'T> -> (string -> 'T option)
val print : ('T -> string)
Multiple items
val string : value:'T -> string
--------------------
type string = System.String
val cases : seq<'T>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
val lookup : Map<string,'T>
module Seq
from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
val case : 'T
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IReadOnlyDictionary<'Key,'Value>
interface IReadOnlyCollection<KeyValuePair<'Key,'Value>>
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
...
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofSeq : elements:seq<'Key * 'T> -> Map<'Key,'T> (requires comparison)
val line : string
val tryFind : key:'Key -> table:Map<'Key,'T> -> 'T option (requires comparison)
val cases<'T> : seq<'T>
type FSharpType =
static member GetExceptionFields : exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
static member GetFunctionElements : functionType:Type -> Type * Type
static member GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
static member GetTupleElements : tupleType:Type -> Type []
static member GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
static member IsExceptionRepresentation : exceptionType:Type * ?bindingFlags:BindingFlags -> bool
static member IsFunction : typ:Type -> bool
static member IsModule : typ:Type -> bool
static member IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
static member IsTuple : typ:Type -> bool
...
static member FSharpType.GetUnionCases : unionType:System.Type * ?allowAccessToPrivateRepresentation:bool -> UnionCaseInfo []
static member FSharpType.GetUnionCases : unionType:System.Type * ?bindingFlags:System.Reflection.BindingFlags -> UnionCaseInfo []
val typeof<'T> : System.Type
val c : UnionCaseInfo
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
...
static member FSharpValue.MakeUnion : unionCase:UnionCaseInfo * args:obj [] * ?allowAccessToPrivateRepresentation:bool -> obj
static member FSharpValue.MakeUnion : unionCase:UnionCaseInfo * args:obj [] * ?bindingFlags:System.Reflection.BindingFlags -> obj
module Array
from Microsoft.FSharp.Collections
val empty<'T> : 'T []
val matchKeyword : (string -> Keyword option)
type 'T option = Option<'T>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
More information