Version française
Home     About     Download     Resources     Contact us    
Browse thread
Polymorphic variants question
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Olivier Andrieu <oandrieu@n...>
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