Type inference vs pointfree style

You’re hitting the value restriction, check the manual’s chapter on 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.

4 Likes