Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f# pattern match on c# classes

I have a C# module that receives and processes various instances of an Operation class. The interface declares one method:

Operation Transform(Operation o1, Operation o2);

But there are several kind of Operations. For simple text editing, for example, there are InsertOperation and DeleteOperation, so the body of the Transform method starts with sorting out what kind of operations it received and casting them. After learning some F# I wanted to rewrite this part of the project in it (as practise and experiment) and thought I could handle this much better with a pattern match like this:

let Transform (oa: Operation) (ob: Operation) = 
    match oa, ob with 
    | InsertOperation o1, InsertOperation o2 -> //transformation
    | DeleteOperation o1, InsertOperation o2 -> //transformation
    | InsertOperation o1, DeleteOperation o2 -> //transformation
    | DeleteOperation o1, DeleteOperation o2 -> //transformation

However, I get the following error message for this:

The pattern discriminator 'InsertOperation' is not defined

The Operation class and its descendants are written in C# but I thought this shouldn't pose a problem. Can someone explain why this is a problem and how I can get around this?

like image 989
Peter Avatar asked Dec 20 '22 07:12

Peter


1 Answers

Since this isn't a discriminated union, but rather just a set of classes (written in C#), you'll need to use a type test pattern:

let Transform (oa: Operation) (ob: Operation) = 
    match oa, ob with 
    | (:? InsertOperation as o1), (:? InsertOperation as o2) -> //transformation
    | (:? DeleteOperation as o1), (:? InsertOperation as o2) -> //transformation
    | (:? InsertOperation as o1), (:? DeleteOperation as o2) -> //transformation
    | (:? DeleteOperation as o1), (:? DeleteOperation as o2) -> //transformation

For details, see Type Test Patterns in Pattern Matching.

like image 68
Reed Copsey Avatar answered Dec 25 '22 22:12

Reed Copsey