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 (19:26) |
From: | Jon Harrop <jon@f...> |
Subject: | Re: [Caml-list] Polymorphic variants question |
On Friday 01 September 2006 18:31, David Allsopp wrote: > let f x = if x = `A then (true, `B) else (false, x);; You probably want: # let f = function `A -> true, `B | `C -> false, `C;; val f : [< `A | `C ] -> bool * [> `B | `C ] = <fun> > then I get a type error unless I change > (false, x) > to > (false, id x) Use coercion :> instead of an ad-hoc function: # let (f : [`A | `C] -> bool * [`A | `B | `C]) = fun x -> if x = `A then (true, `B) else (false, (x :> [`A|`B|`C]));; val f : [ `A | `C ] -> bool * [ `A | `B | `C ] = <fun> > 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. Note that the type of your id function is not 'a -> 'a: # let id = function `A -> `A | `C -> `C;; val id : [< `A | `C ] -> [> `A | `C ] = <fun> So it accepts a subset of {A, C} and returns a type that unifies with any superset of {A, C}. To leverage static type checking you must provide as much information as possible to the static type checker. In this case, rather than using "if" to denote `A or not `A, you can just as easily use pattern matching to imply specifically `A or `C. -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. Objective CAML for Scientists http://www.ffconsultancy.com/products/ocaml_for_scientists