Reputation: 6175
Let two variant types :
type typeA =
| A1
| A2
;;
type typeB =
| B1 of typeA
| B2 of typeA
;;
and type-checking functions :
let isA1 = function A1 -> true | _ -> false;;
let isA2 = function A2 -> true | _ -> false;;
let isB1 = function B1 e -> true | _ -> false;;
let isB2 = function B2 e -> true | _ -> false;;
I'd like to create a list of those functions to check elements of type A or B
as they're of different types, I need polymorphic variants and I get :
type filterA =
{
handleA : typeA -> bool;
};;
type filterB =
{
handleB : typeB -> bool;
};;
type filterslist = [`FilterA of filterA | `FilterB of filterB] list ;;
let filters1 = [`FilterA { handleA = isA1 }; `FilterB { handleB = isB1 }] ;;
So now I want to iterate over filters1 to check the type of the argument I tried :
let exec_filters filters event = List.iter (fun fil -> match fil with `FilterA -> fil.handleA event; ()| `FilterB -> fil.handleB event; () ) filters;;
but it's not appreciated :
Error: This expression has type [< `FilterA | `FilterB ]
but an expression was expected of type filterA
How can I handle this ?
Upvotes: 3
Views: 357
Reputation: 9437
I think your code should read like:
let exec_filters filters event =
List.iter
(fun fil -> match fil with
| `FilterA fA -> fA.handleA event; ()
| `FilterB fB -> fB.handleB event; () )
filters;;
EDIT: However, this won't typecheck, since event
can't have types typeA
and typeB
...
Why not make your initial variants (typeA
and typeB
) polymorphic?
What are you trying to do?
Upvotes: 4
Reputation: 66808
When you say
match fil with
`FilterA -> ...
You seem to expect that this will change the type of fil
, but that's not how it works. The expression with the type filterA
appears inside the pattern. You want something more like this:
match fil with
`FilterA { handleA = h } -> h event
I'm not sure I see the purpose of having your handlers return bool
if you're going to use List.iter
to execute them. This will return unit
, and the bool
values are going to be discarded.
Edit
There's a deeper typing problem, explained well by Ptival. So even if you fix your patterns you'll still need to rethink your plan. One possible thing to do would be to use variants (not necessarily polymorphic variants, by the way) to track the types of the events.
Upvotes: 2
Reputation: 7672
The fact that you're using "type checking predicates" similar to Scheme or instanceOf indicates that there is probably something very wrong with your code. OCaml is a statically typed language, you should not:
iterate over filters1 to check the type of the argument I tried
Why are you doing this? If you are trying to handle multiple types, the way to do it is to use polymorphism. Polymorphic variants can be helpful for this, but I'm still not convinced that your code isn't just written in a strange way.
Upvotes: 5