6 people like it.

Generic TryParse active pattern

We can use active patterns for parsing values of types with defined TryParse methods.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
let inline (|Parse|_|) (str: string): ^a option =
    let mutable value = Unchecked.defaultof< ^a>
    let result = (^a: (static member TryParse: string * byref< ^a> -> bool) str, &value)
    if result then Some value
    else None
   
let foobar str =
    match str with
    | Parse(x: int) -> "int"
    | Parse(x: float) -> "float"
    | Parse(x: System.Guid) -> "guid"
    | _ -> "other"
    
printfn "%s" (foobar "42")
val str : string
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
type 'T option = Option<'T>
val mutable value : 'a (requires member TryParse)
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T
val result : bool
type byref<'T> = (# "<Common IL Type Omitted>" #)
type bool = System.Boolean
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val foobar : str:string -> string
active recognizer Parse: string -> 'a option
val x : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
val x : float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

--------------------
type float = System.Double

--------------------
type float<'Measure> = float
val x : System.Guid
namespace System
Multiple items
type Guid =
  struct
    new : b:byte[] -> Guid + 5 overloads
    member CompareTo : value:obj -> int + 1 overload
    member Equals : o:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member ToByteArray : unit -> byte[]
    member ToString : unit -> string + 2 overloads
    member TryFormat : destination:Span<char> * charsWritten:int * ?format:ReadOnlySpan<char> -> bool
    member TryWriteBytes : destination:Span<byte> -> bool
    static val Empty : Guid
    static member NewGuid : unit -> Guid
    ...
  end

--------------------
System.Guid ()
System.Guid(b: byte []) : System.Guid
System.Guid(b: System.ReadOnlySpan<byte>) : System.Guid
System.Guid(g: string) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte []) : System.Guid
System.Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Raw view Test code New version

More information

Link:http://fssnip.net/80v
Posted:3 years ago
Author:Evgeniy Andreev
Tags: #active patterns , #srtp