Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value not polymorphic enough

Tags:

ocaml

Here's a minimal example out of my code demonstrating the problem:

module Substring = struct
  type t = {
    base: string;
    pos: int;
    len: int
  }
end

module Parser = struct
  type 'a t = Substring.t -> ('a * Substring.t) option
  let return x s = Some (x, s)
end

type (_, _) t =
  | TryParse : unit Parser.t -> ('a, 'a) t
  | Parse    : 'b Parser.t -> ('a, 'b -> 'a) t
  | Concat   : ('b, 'c) t * ('a, 'b) t -> ('a, 'c) t

let p = Parse (Parser.return "xxx")

My problem is that I want val p : ('a, string -> 'a) t to be polymorphic and yet OCaml makes 'a weak: val p : ('_a, string -> '_a). I'm pretty sure I'm being bitten by the value restriction here and I'm not quite sure how to get around it.

like image 218
rgrinberg Avatar asked Dec 06 '14 22:12

rgrinberg


1 Answers

Yes, this is the value restriction. You need to eta-expand the problematic definition, like this:

let p = Parse (fun x -> Parser.return "xxx" x)

Annoying, isn't it?

If you want a binding to be polymorphic then you usually have to ensure that it is a "syntactic value". An expression containing a partial application doesn't qualify (because in general partial applications may have an effect), but a (fun ...) is fine.

like image 128
gsg Avatar answered Nov 18 '22 09:11

gsg