This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

Polymorphic variants question
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
 Date: 2006-09-01 (18:40) From: Olivier Andrieu Subject: Re: [Caml-list] Polymorphic variants question
``` David Allsopp [Friday 1 September 2006] :
>
> Forgive the potentially obvious question --- I'm not very familiar with
> polymorphic variants but I think that they're what I want in this situation!
>
> Suppose I'm dealing with three constructors `A, `B and `C and I have a
> function f that's supposed to take either `A or `C and return any of `A, `B
> or `C. If I write:
>
> let f x = if x = `A then (true, `B) else (false, x)
>
> then I get the type
>
> val f : ([> `A | `B] as 'a) -> bool * 'a
>
> Now, if I try to constrain it to what I'm after with
>
> let (f : [`A | `C] -> bool * [`A | `B | `C]) = fun x -> ...
>
> then I get a type error unless I change
> 	(false, x)
> to
> 	(false, id x)
> with
> 	let id = function `A -> `A | `C -> `C
>
> Is there a better way of writing this? I'm using this in the context of
> several interrelated lexers where `A, `B and `C are high-level states and
> certain lexers can only be called in a subset of those states but each lexer
> may yield any value for the next-state. I'd quite like to eliminate the id x
> bit since it's only there to "separate" x from the return value for the
> type-checker.

you can use pattern-matching with a "as" pattern to introduce another
identifier for your value in the non-`A branch :
,----
| # let f = function
|   | `A -> true, `B
|   | `C as x -> false, x ;;
| val f : [< `A | `C ] -> bool * [> `B | `C ] = <fun>
`----
(the [> `B | `C ] return type can be constrained to [`A`B|`C] if you
want)

--
Olivier

```