Thanks so much. On Mon, Mar 28, 2016, 1:08 AM Gabriel Scherer wrote: > Locally abstract types scope over the definition body where they can > be used as type names or to refine GADTs by pattern-matching. > > module type Ty = sig type t end > > (* we need the scoping of the locally abstract type in this example; > note that (type a) would work as well *) > let mkTy : type a . unit -> (module Ty with type t = a) = > fun () -> > let module T = struct type t = a end in > (module T) > > > val mkTy : unit -> (module Ty with type t = 'a) = > > (* a type variable 'a only scopes over the type annotation *) > let mkTy : 'a . unit -> (module Ty with type t = 'a) = > fun () -> > let module T = struct type t = 'a end in > (module T) > > > let module T = struct type t = 'a end in > > ^^ > > Error: Unbound type parameter 'a > > > type _ tag = Int : int tag | Prod : 'a tag * 'b tag -> ('a * 'b) tag > > (* we need the ability to be refined by GADT matching here *) > let rec default : type a . a tag -> a = > function > | Int -> 0 > | Prod (ta, tb) -> (default ta, default tb) > > > val default : 'a tag -> 'a = > > (* a type variable just unifies with the first case and fails on the > second *) > let rec default : 'a . 'a tag -> 'a = > function > | Int -> 0 > | Prod (ta, tb) -> (default ta, default tb) > > ^^^^^^^^^^^^^ > > Error: This pattern matches values of type ($0 * $1) tag > > but a pattern was expected which matches values of type int tag > > Type $0 * $1 is not compatible with type int > > (* the difference by "(type a) ..." and "type a . ..." is that the latter > allows polymorphic recursion (just as "'a . ..."), so this example fails > with just (type a) *) > let rec default (type a) : a tag -> a = > function > | Int -> 0 > | Prod (ta, tb) -> (default ta, default tb) > > ^^ > > Error: This expression has type $0 tag but an expression > > was expected of type 'a > > The type constructor $0 would escape its scope > > > On Mon, Mar 28, 2016 at 6:20 AM, Gregory Malecha > wrote: > > Thanks. I'm not sure I understand the difference between the two though. > Is > > there an example showing when they produce different results? > > > > On Sun, Mar 27, 2016 at 6:12 PM, Jacques Garrigue > > wrote: > >> > >> On 2016/03/28 03:52, Gregory Malecha wrote: > >> > > >> > Thanks, Leo -- > >> > > >> > This is exactly what I needed to know. I thought that the (type a) > >> > annotation was forcing the function to be polymorphic. For future > reference, > >> > is there any way to write the annotation (that forces the function to > be > >> > polymorphic) without having to write explicit ‘fun's? > >> > >> You should either write > >> > >> let generic_search_stream : ‘b. int option -> (internal_result, ‘b) > >> result_stream = … > >> > >> or > >> > >> let generic_search_stream : type b. int option -> (internal_result, b) > >> result_stream = … > >> > >> where the latter one both requires polymorphism and defines a locally > >> abstract type, > >> i.e. probably the behavior you expect with (type b). > >> > >> Jacques > >> > > > > > > > > -- > > gregory malecha >