# Type inference vs pointfree style

**URL:** <https://discuss.ocaml.org/t/type-inference-vs-pointfree-style/15781>\
**Category:** Learning\
**Tags:** type-inference, type-system\
**Created:** [December 12, 2024, 1:11am UTC](https://discuss.ocaml.org/t/type-inference-vs-pointfree-style/15781 "2024-12-12T01:11:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![kidq330](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/kidq330/32/5690_2.png) [@kidq330](https://discuss.ocaml.org/u/kidq330)\
**Post date:** [December 12, 2024, 1:11am UTC](https://discuss.ocaml.org/t/type-inference-vs-pointfree-style/15781/1 "2024-12-12T01:11:09Z")

</div>

Hi OCaml community,  
Coming from Haskell and about to write a uni project using Frama-C, so I’m currently doing Advent of Code in OCaml to get more comfortable, here’s a quirk I came upon

.ml file:

```auto
type 'a my_type = 'a -> unit

let foo (_ : 'a) = ()
let bar = Fun.id foo

```

.mli file:

```auto
type 'a my_type = 'a -> unit

val foo : 'a my_type
val bar : 'a my_type

```

```auto
λ> dune b 
File "lib/ocaml_bug.ml", line 1:   
Error: The implementation lib/ocaml_bug.ml
       does not match the interface lib/ocaml_bug.ml: 
       Values do not match:
         val bar : '_weak1 -> unit
       is not included in
         val bar : 'a my_type
       The type '_weak1 -> unit is not compatible with the type
         'a my_type = 'a -> unit
       Type '_weak1 is not compatible with type 'a
       File "lib/ocaml_bug.mli", line 4, characters 0-20:
         Expected declaration
       File "lib/ocaml_bug.ml", line 4, characters 4-7: Actual declaration

```

I’ve tried many variations of implementing `foo` and `bar` and it only seems like specifying an actual argument for `bar` resolves the issue. Why is this?

---

<div class="post-metadata">

**Author:** ![amongonz](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@amongonz](https://discuss.ocaml.org/u/amongonz)\
**Post date:** [December 12, 2024, 3:11am UTC](https://discuss.ocaml.org/t/type-inference-vs-pointfree-style/15781/2 "2024-12-12T03:11:42Z")

</div>

You’re hitting the _value restriction_, check [the manual’s chapter on weak polymorphism](https://ocaml.org/manual/5.2/polymorphism.html#s:weak-polymorphism).

For short, the compiler assumes that the return value of `Fun.id foo` could hide mutation effects, which would make the more general type unsound, so it uses a weaker kind of type variables that can’t generalize. This looks a bit funny for obviously pure functions, but that can’t be tracked without complicating the type system.

Adding a parameter for `bar` fixes this because that turns it back into a function definition, which visibly delays the call to `Fun.id foo` and thus can’t leak polymorphic values across calls. In other words, knowing you come from Haskell: eta-expansion delays side effects.
