I have an expression using pipe operator that converts the value to string and then to bool, however sometimes the original value can be null. How can I use the pattern matching or something else to assume false when the value is null?
type kv = Dictionary<string, obj>
let allDayEvent (d: kv) = d.["fAllDayEvent"] |> string |> bool.Parse
There's quite a few places where you can safeguard via pattern matching: dictionary lookup, casting, parsing. Here's an example with all of those:
let allDayEvent (d: kv) =
match d.TryGetValue "fAllDayEvent" with
| true, v ->
match v with
| null -> printfn "null found"
| :? string as s ->
match bool.TryParse s with
| true, b -> printfn "found a bool: %A" b
| _ -> printfn "That's not a bool?"
| v -> printfn "Found something of type %s" (v.GetType().Name)
| _ -> printfn "No such key"
See also related questions, for example this.
Not sure why you are using a Dictionary, but I would probably have gone for a Map instead. Or at least done some Conversion to Map somewhere. And then I would maybe have thrown in some "automagically" handling of nulls.
And then Pandoras Box is kind of opened, but....
let (|Bool|) str =
match System.Boolean.TryParse(str) with
| (true,bool) -> Some(bool)
| _ -> None
let (|String|) (o:obj) =
match o with
| :? string as s -> Some(s)
| _ -> None
type kv = Dictionary<string, obj>
let allDayEvent (d: kv) =
d :> seq<_>
|> Seq.map (|KeyValue|)
|> Map.ofSeq
|> Map.tryFind "fAllDayEvent"
|> Option.bind (|String|)
|> Option.bind (|Bool|)
Note that allDayEvent in the above now is an Option, which maybe is in fact what you need/want.
And it does keep all data in place. Like true or false is not the same as "did not find stuff" or "could not convert stuff to some bool". Now it is in fact one of the following:
- key found and some string like "true": Some(true)
- key found and some string like "false": Some(false)
- key not found or string not convertable to bool: None
Code is not tested and may need some further massaging.
来源:https://stackoverflow.com/questions/41570314/error-using-bool-parse-on-null-empty-values