Reputation: 1917
This is another follow-up to Working with missing values in Deedle Time Series in F# (2)
I have written this function to map2 series, returning a missing value when either input is missing.
let map2series (f:'T1->'T2->'R)(series1:Series<'K,'T1 opt>)(series2:Series<'K,'T2 opt>):Series<'K,'R opt>=
let S = series1.Zip(series2,JoinKind.Outer) //Series<'K,('T1 opt opt * 'T2 opt opt)>
S |> Series.mapValues (fun (a,b) -> match (a,b) with
| (OptionalValue.Present(a'), OptionalValue.Present(b')) -> OptionalValue.map2 f a' b'
| _ -> OptionalValue.Missing)
since Series<'K,'T opt>
appear naturally in Deedle after using .Zip
or .Join
methods.
However, as seen previously, Series<'K,'V>
already supports missing values, so I'd like to rewrite the function above that basically would do the same except that it takes Series<'K,'V>
as inputs
let map2series1 (f:'T1->'T2->'R)(series1:Series<'K,'T1>)(series2:Series<'K,'T2>):Series<'K,'R>=
let S = series1.Zip(series2,JoinKind.Outer) //Series<'K,('T1 opt * 'T2 opt)>
S |> Series.mapValues (fun (a,b) -> match (a,b) with
| (OptionalValue.Present(a'), OptionalValue.Present(b')) -> f a' b'
| _ -> None)
However this doesn't work, i don't have the right syntax in the second union case when one value is missing...
basically instead of the last None
, i need to assign a value which corresponds to <missing>
but i can't find it.
I also looked at something like
Option.bind OptionalValue.asOption OptionalValue.Missing
but cannot find the right expression
Upvotes: 3
Views: 124
Reputation: 2220
You can do it this way:
let map2 f =
function
| OptionalValue.Present(a'), OptionalValue.Present(b') -> Some (f a' b')
| _ -> None
let map2series f series1 series2 =
series2
|> Series.zip series1
|> Series.mapAll(fun _ -> Option.bind(map2 f))
Upvotes: 1