0 people like it.

Functional wrappers for TryParse APIs

Exemplary convenience wrappers for some of the System..TryParse APIs, using the combined power of F#' return value deconstruction mechanism via pattern matching, active patterns and option types instead of "out/ref" parameters. Added support for newest versions of F# to determine which overload of TryParse should be used.

 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: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
// see also 
// http://stackoverflow.com/questions/4949941/convert-string-to-system-datetime-in-f

module TryParser =
    // convenient, functional TryParse wrappers returning option<'a>
    let tryParseWith (tryParseFunc: string -> bool * _) = tryParseFunc >> function
        | true, v    -> Some v
        | false, _   -> None

    let parseDate   = tryParseWith System.DateTime.TryParse
    let parseInt    = tryParseWith System.Int32.TryParse
    let parseSingle = tryParseWith System.Single.TryParse >> Option.filter System.Single.IsFinite
    let parseDouble = tryParseWith System.Double.TryParse
    // etc.

    // active patterns for try-parsing strings
    let (|Date|_|)   = parseDate
    let (|Int|_|)    = parseInt
    let (|Single|_|) = parseSingle
    let (|Double|_|) = parseDouble

open TryParser

// tests
let parseMe = function
    | Date d   -> printfn "DateTime %A" d
    | Int 42   -> printfn "Bingo!"
    | Int i    -> printfn "Int32 %i" i
    | Single f -> printfn "Single %g" f
    | Double d -> printfn "Double %g" d
    | s        -> printfn "Don't know how to parse %A" s

parseMe "213"
parseMe "2010-02-22"
parseMe "3,0"
parseMe "jslkdfjlkj"
parseMe "42"
parseMe "3.40282e+39"
val tryParseWith : tryParseFunc:(string -> bool * 'a) -> (string -> 'a option)
val tryParseFunc : (string -> bool * 'a)
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
[<Struct>]
type bool = System.Boolean
val v : 'a
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val parseDate : (string -> System.DateTime option)
namespace System
Multiple items
[<Struct>]
type DateTime =
  new : ticks: int64 -> unit + 13 overloads
  member Add : value: TimeSpan -> DateTime + 1 overload
  member AddDays : value: float -> DateTime
  member AddHours : value: float -> DateTime
  member AddMilliseconds : value: float -> DateTime
  member AddMinutes : value: float -> DateTime
  member AddMonths : months: int -> DateTime
  member AddSeconds : value: float -> DateTime
  member AddTicks : value: int64 -> DateTime
  member AddYears : value: int -> DateTime
  ...

--------------------
System.DateTime ()
   (+0 other overloads)
System.DateTime(ticks: int64) : System.DateTime
   (+0 other overloads)
System.DateTime(ticks: int64, kind: System.DateTimeKind) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : System.DateTime
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : System.DateTime
   (+0 other overloads)
System.DateTime.TryParse(s: System.ReadOnlySpan<char>, result: byref<System.DateTime>) : bool
System.DateTime.TryParse(s: string, result: byref<System.DateTime>) : bool
System.DateTime.TryParse(s: System.ReadOnlySpan<char>, provider: System.IFormatProvider, styles: System.Globalization.DateTimeStyles, result: byref<System.DateTime>) : bool
System.DateTime.TryParse(s: string, provider: System.IFormatProvider, styles: System.Globalization.DateTimeStyles, result: byref<System.DateTime>) : bool
val parseInt : (string -> int option)
[<Struct>]
type Int32 =
  member CompareTo : value: obj -> int + 1 overload
  member Equals : obj: obj -> bool + 1 overload
  member GetHashCode : unit -> int
  member GetTypeCode : unit -> TypeCode
  member System.IConvertible.ToBoolean : provider: IFormatProvider -> bool
  member System.IConvertible.ToByte : provider: IFormatProvider -> byte
  member System.IConvertible.ToChar : provider: IFormatProvider -> char
  member System.IConvertible.ToDateTime : provider: IFormatProvider -> DateTime
  member System.IConvertible.ToDecimal : provider: IFormatProvider -> decimal
  member System.IConvertible.ToDouble : provider: IFormatProvider -> float
  ...
System.Int32.TryParse(s: System.ReadOnlySpan<char>, result: byref<int>) : bool
System.Int32.TryParse(s: string, result: byref<int>) : bool
System.Int32.TryParse(s: System.ReadOnlySpan<char>, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<int>) : bool
System.Int32.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<int>) : bool
val parseSingle : (string -> float32 option)
[<Struct>]
type Single =
  member CompareTo : value: obj -> int + 1 overload
  member Equals : obj: obj -> bool + 1 overload
  member GetHashCode : unit -> int
  member GetTypeCode : unit -> TypeCode
  member System.IConvertible.ToBoolean : provider: IFormatProvider -> bool
  member System.IConvertible.ToByte : provider: IFormatProvider -> byte
  member System.IConvertible.ToChar : provider: IFormatProvider -> char
  member System.IConvertible.ToDateTime : provider: IFormatProvider -> DateTime
  member System.IConvertible.ToDecimal : provider: IFormatProvider -> decimal
  member System.IConvertible.ToDouble : provider: IFormatProvider -> float
  ...
System.Single.TryParse(s: System.ReadOnlySpan<char>, result: byref<float32>) : bool
System.Single.TryParse(s: string, result: byref<float32>) : bool
System.Single.TryParse(s: System.ReadOnlySpan<char>, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<float32>) : bool
System.Single.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<float32>) : bool
module Option

from Microsoft.FSharp.Core
val filter : predicate:('T -> bool) -> option:'T option -> 'T option
System.Single.IsFinite(f: float32) : bool
val parseDouble : (string -> float option)
[<Struct>]
type Double =
  member CompareTo : value: obj -> int + 1 overload
  member Equals : obj: obj -> bool + 1 overload
  member GetHashCode : unit -> int
  member GetTypeCode : unit -> TypeCode
  member System.IConvertible.ToBoolean : provider: IFormatProvider -> bool
  member System.IConvertible.ToByte : provider: IFormatProvider -> byte
  member System.IConvertible.ToChar : provider: IFormatProvider -> char
  member System.IConvertible.ToDateTime : provider: IFormatProvider -> DateTime
  member System.IConvertible.ToDecimal : provider: IFormatProvider -> decimal
  member System.IConvertible.ToDouble : provider: IFormatProvider -> float
  ...
System.Double.TryParse(s: System.ReadOnlySpan<char>, result: byref<float>) : bool
System.Double.TryParse(s: string, result: byref<float>) : bool
System.Double.TryParse(s: System.ReadOnlySpan<char>, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<float>) : bool
System.Double.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<float>) : bool
module TryParser

from Script
val parseMe : _arg1:string -> unit
active recognizer Date: string -> System.DateTime option
val d : System.DateTime
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
active recognizer Int: string -> int option
val i : int
active recognizer Single: string -> float32 option
val f : float32
active recognizer Double: string -> float option
val d : float
val s : string

More information

Link:http://fssnip.net/2y
Posted:4 days ago
Author:Cody
Tags: parsing , pattern matching , active patterns , wrapper