# Request help with type error

**URL:** <https://discuss.ocaml.org/t/request-help-with-type-error/2408>\
**Category:** Learning\
**Created:** [August 8, 2018, 12:59pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408 "2018-08-08T12:59:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [August 8, 2018, 12:59pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/1 "2018-08-08T12:59:35Z")

</div>

Hi.

I have the following:

```
module Make_enum(X:sig type t end) = struct
  open X

  (* nts are even, tms are odd; we maintain a mapping *)
  type t_enum = {
    mutable free:int;
  }

  let make = 
    let enum = { free=0 } in 
    let somefun = fun (s:t) -> 3 in
    fun f -> f ~somefun
end 

type t' = Something

module X = struct type t = t' end

module Made = Make_enum(X)

let f = Made.make @@ fun ~somefun -> somefun

```

Unfortunately there is a type error in the last line (let f = …):

```
File "tmp.ml", line 21, characters 37-44:
Error: This expression has type t' -> int
       but an expression was expected of type 'a
       The type constructor t' would escape its scope

```

I don’t understand this because t’ is in scope.

On the other hand, the following is fine:

```
module Make_enum(X:sig type t end) = struct
  open X

  (* nts are even, tms are odd; we maintain a mapping *)
  type t_enum = {
    mutable free:int;
  }

  let make () = 
    let enum = { free=0 } in 
    let somefun = fun (s:t) -> 3 in
    fun f -> f ~somefun
end 

type t' = Something

module X = struct type t = t' end

module Made = Make_enum(X)

let f = Made.make () @@ fun ~somefun -> somefun

```

But I’m not sure why this is fine when the first example isn’t.

Thanks

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [August 8, 2018, 1:00pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/2 "2018-08-08T13:00:16Z")

</div>

BTW this is OCaml 4.04.2

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [August 8, 2018, 1:35pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/3 "2018-08-08T13:35:14Z")

</div>

The root cause of your issue is that you first version of `make` is [weakly polymorphic due to the value restriction](http://caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html#sec53). Using 4.06 notation, its type is

```Ocaml
     val make : (somefun:(X.t -> int) -> '_weak1) -> '_weak1

```

Then when you apply `Made.make`, the typechecker try to unify `'_weak1` with `t'` but this is not allowed because `t'` was defined after the introduction of `'_weak1`. A simpler example of this problem can be seen in

```OCaml
let x = ref []
type t = A
;;
x := [A]

```

> Error: This expression has type t but an expression was expected of type 'weak2  
> The type constructor t would escape its scope

The scope error is the typechecker pointing at the fact that `'weak2` was introduced before the definition of `t`.

The simplest way to fix your issue might be to make `make` polymorphic by moving the definition of the mutable enum before the definition of `make`:

```OCaml
  let enum = { free=0 }
  let make = 
    let somefun = fun (s:t) -> 3 in
    fun f -> f ~somefun

```

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [August 8, 2018, 2:14pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/4 "2018-08-08T14:14:42Z")

</div>

Ah, OK. Thank you.

* * *

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [August 8, 2018, 2:19pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/5 "2018-08-08T14:19:22Z")

</div>

I think if I had seen the inferred module signature I would have spotted the weakly polymorphic type var. Your explanation makes perfect sense.

Thanks

---

<div class="post-metadata">

**Author:** ![perry](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/perry/32/518_2.png) [@perry](https://discuss.ocaml.org/u/perry)\
**Post date:** [August 8, 2018, 5:18pm UTC](https://discuss.ocaml.org/t/request-help-with-type-error/2408/6 "2018-08-08T17:18:48Z")

</div>

For those looking at this in the future, I will point out this great article on the value restriction: [https://ocamlverse.github.io/content/weak\_type\_variables.html](https://ocamlverse.github.io/content/weak_type_variables.html)
