Reputation: 5394
How do I fix the following errors?
This expression was expected to have type 'string * Nullable * Nullable' but here has type 'VisitType' (Error occurs on "|AppointmentOnly(q.lastname, q.posting_time)).
and
Field 'appointmentTime' is not static (Error occurs on FsVisit.appointmentTime = q.appointment_time;).
(These errors occur in my attempt to download records from a PostgreSQL database via WCF into F# client).
type VisitType =
| AppointmentOnly of name: string * postedTime: DateTime
| WalkIn of name: string * serviceTime: DateTime
| Kept of name: string * postedTime: DateTime * serviceTime: DateTime
| Open
type FsVisit =
{ appointmentTime: Nullable<DateTime>
visitType: VisitType }
with
member this.Name =
match this.visitType with
| AppointmentOnly(name=name) | WalkIn(name=name) | Kept(name=name) -> Some name
| Open -> None
let TestGetScheduleAsync (tableDate : DateTime) =
async {
let! data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map ( fun q ->
FsVisit.appointmentTime = q.appointment_time;
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(q.lastname, q.posting_time) -> AppointmentOnly({name = q.lastname; postedTime = q.posting_time})
| WalkIn(q.lastname, q.service_time) -> WalkIn({name =q.lastname; serviceTime = q.service_time})
| Kept(q.lastname, q.posting_time, q.service_time) -> Kept({name=q.lastname; postedTime = q.posting_time, serviceTime = q.service_time})
| Open -> None
)}
|> Async.StartAsTask
Thank you for any help.
Upvotes: 1
Views: 63
Reputation: 236248
Tuple of lastname
, posting_time
, and service_time
is not a value of VisitType
type. So you cannot match it with VisitType
discriminated union cases. I assume that posting_time
and service_time
are Nullable<DateTime>
values (same as appointment_time
) So you should match tuple with tuple and create VisitType
case depending on posting_time
and service_time
value (Some
or None
). I also would remove name from matching
match (Option.ofNullable q.posting_time, Option.ofNullable q.service_time) with
| (Some postedTime, None) -> AppointmentOnly(q.lastname, postedTime)
| (None, Some serviceTime) -> WalkIn(q.lastname, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(q.lastname, postedTime, serviceTime)
| _ -> Open
You can adjust this code if you want VisitType option
by returning None
for Open
case and Some
for other cases.
Note that your code can be compilable as well if you'll add active patterns which will create so-called named partitions for your input data (tuple):
let (|AppointmentOnly|WalkIn|Kept|Open|)
(name: string, postedTime: Nullable<DateTime>, serviceTime: Nullable<DateTime>) =
match (Option.ofNullable postedTime, Option.ofNullable serviceTime) with
| (Some postedTime, None) -> AppointmentOnly(name, postedTime)
| (None, Some serviceTime) -> WalkIn(name, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(name, postedTime, serviceTime)
| (None, None) -> Open
Keep in mind that AppointementOnly
, WalkIn
, Kept
, Open
returned here is not a discriminated union cases - it's an active pattern records. Now you can use this active pattern to divide your input data into partitions and create corresponding VisitType
cases:
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
| WalkIn(name, serviceTime) -> WalkIn(name, serviceTime)
| Kept(name, postedTime, serviceTime) -> Kept(name, postedTime, serviceTime)
| Open -> Open
Again, here we are matching on the active pattern and then creating a discriminated union:
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
^ ^
ACTIVE PATTERN IDENTIFIER UNION CASE
Upvotes: 1