Browse thread
Polymorphic variants question
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2006-09-01 (18:40) |
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