In Hindley-Milner (HM) type inference, polymorphism is achieved through 'let polymorphism' where type schemes are generalized at let bindings and instantiated at uses; generalization creates a universally quantified type scheme (e.g., α.α→α) by applying constraints and removing type variables that appear in the surrounding environment, while instantiation replaces quantified type variables with fresh type variables when the function is used, allowing each application to have its own specific type.
Let Polymorphism: Type Schemes in HM Inference (OCaml) | Chapter 9
Added:so here's how ocamel and hm type inference uses this idea of type schemes when you get to a polymorphic function like this say id which has type alpha arrow alpha the type inference algorithm will actually generalize that type to a type scheme so it'll take that alpha arrow alpha and generalize it to alpha dot alpha arrow alpha think of that as generalizing in the sense of universal quantification it's saying for all alpha the function has that type then at each use of the function at each application of it type inference will instantiate that type with a new type variable so it's like filling in that universal quantification with something more specific now at the application of id to zero we might extension it then to say beta aero beta assuming beta is a fresh type variable and then later at the application of id to true it would get instantiated with a different type variable say gamma arrow gamma now each use of the function is independent of the other uses of the function so each usage can end up having its own type whether that's interro int or bool arrow bool to make use of generalization and instantiation we just need to update two rules in little ways so the naive let rule we gave is almost correct it's just we need to generalize a piece of it so when we go to put the type t1 of the binding expression e1 into the environment we generalize it to create a type scheme now the slight complication there is we need some additional information in order to do the generalization correctly we need to know the constraints that were generated the environment and the name of the variable so that's why the call to generalize occurs outside of all of those i'll show you what that looks like in just the name rule is the other one we need to update here we need to instantiate any type scheme we discover when we use the name of a variable so instantiation then in more detail if you apply instantiate to a type strictly speaking a type not a type scheme so there's no quantification going on it does it doesn't change it just leaves types unchanged but when you instantiate a type scheme you're changing it back into a type you get rid of the alpha one alpha two alpha n whatever however many there are dots in front of it and you substitute a fresh type variable for each of them so if you had something like the identity function which would be alpha dot alpha arrow alpha that would become beta arrow beta for a fresh beta generalization is the harder one of the two so it takes these three or maybe four inputs here a constraint set a static environment a name of a variable and the type that was initially found for that variable that we're now possibly going to general here's what generalize does it fully finishes inference of that binding expression so it's like we're going to stop here we're going to worry about the rest of the program for a minute we're going to take that constraint set c1 and unify it that'll get us a substitution we then apply that substitution to the environment so we're sort of mining that substitution for all the information we can get out from it we also apply it to the type t1 so that gets us a new environment let's call it end one and a new type let's call it u1 now we generalize u1 so we had fully finished inference for it we look at it and say are there any type variables here we could generalize and turn this into a type scheme now you might start off by saying well i could generalize all the type variables in fact there are some that maybe should not be general and those are any type variables that also show up still in the static environment and the reason for that is they come from surrounding code code outside of the lead expression that we're currently working on right it must be nested inside something else that itself bound some name so we don't want to generalize those because the outside environment already has some assumptions about those type variables maybe it's going to use them someplace else maybe there's constraints that are going to emerge about those someplace else so we don't allow those to be general generalize then returns that environment that had the substitution applied to it as well as the binding of x to this generalized type scheme s1 this is what makes polymorphic type inference work this is in a way the essence of hm type inference that it does this generalization to type schemes at let bindings and so sometimes this way of doing type inference is referred to as let polymorphism
Up Next

Resolution in First-Order Logic Explained | AI Lecture 48
@iit
9.3K views•2014-05-06

BitTorrent Protocol Explained: Piece Selection & Peer Choking
@StevenGordonAU
481 views•2013-02-22

HM Type Inference: Constants and Names | OCaml Programming
@MichaelRyanClarkson
2.7K views•2021-08-08

Enigma Machine Mechanics: WWII Encryption Explained
@JaredOwen
13.2M views•2021-12-11
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Computer Science




















![[ML24] Rethinking the Value Restriction](https://i.ytimg.com/vi_webp/C1g_PO_xcI8/maxresdefault.webp)
![Foundations of Programming Languages: Polymorphic Lambda-Calculus [2/2] - Paul Downen - OPLSS 2018](https://i.ytimg.com/vi/hpParnOeC08/sddefault.jpg)



![[PLDI'25] Practical Type Inference with Levels](https://i.ytimg.com/vi_webp/u85Cv1oKdV4/maxresdefault.webp)









![Records, sums, cases, and exceptions: Row-polymorphism at work [1/9]](https://i.ytimg.com/vi/l6ibFW82hYk/hqdefault.jpg)

![[ICFP'23] Generic Programming with Extensible Data Types: Or, Making Ad Hoc Extensible Dat...](https://i.ytimg.com/vi/ZAUBtISINj0/maxresdefault.jpg)

