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.