Alexander Zeitler
Alexander Zeitler

Reputation: 13109

Pattern match multiple dates

According to this answer, I can match against DateTime.MinValue like this:

let result = 
  match date with 
  | d when d = DateTime.MinValue -> 1
  | _                            -> 0

How do I do this, if I have a match like this?

let result = 
  match (startDate, endDate) with 

This doesn't work:

let result = 
  match (startDate, endDate) with 
  | d when d = DateTime.MinValue, e when e = DateTime.MinValue  -> 0

Compiler error for the second when:

Unexpected keyword 'when' in pattern matching. Expected '->' or other token.

Upvotes: 1

Views: 87

Answers (3)

David Raab
David Raab

Reputation: 4488

I also would use a partial active pattern. But i would add arguments to the pattern that makes it more re-usable.

let (|IsEqual|_|) shouldBe actual =
    if actual = shouldBe then Some actual else None

let isMinDate startDate endDate =
    match startDate, endDate with
    | IsEqual DateTime.MinValue d, IsEqual DateTime.MinValue e -> 1
    | _ -> 0

Upvotes: 0

kaefer
kaefer

Reputation: 5751

A possible alternative might be a partial active pattern, by moving part of the logic into it. The rule is matched when all tupled patterns are matched, and a partial active pattern is matched when it returns a Some value.

The partial active pattern here is of type DateTime -> unit option, as we going to ignore the return value anyway.

let (|IsMinValue|_|) d =
    if d = DateTime.MinValue then Some() else None
    
match startDate, endDate with
| IsMinValue, IsMinValue -> 0
| _ -> 1

Upvotes: 4

Tarmil
Tarmil

Reputation: 11372

when can be added to a whole pattern, not to nested patterns, so you need something like this:

match (startDate, endDate) with
| d, e when d = DateTime.MinValue && e = DateTime.MinValue -> 0
| _ -> 1

Note that in this case, pattern matching is not really necessary, and you can go for a simpler if:

if d = DateTime.MinValue && e = DateTime.MinValue then
    0
else
    1

Upvotes: 4

Related Questions