I've read that Go doesn't actually have true type inference in the sense that functional languages such as ML or Haskell have, but I haven't been able to find a simple to understand comparison of the two versions. Could someone explain in basic terms how type inference in Go differs from type inference in Haskell, and the pros/cons of each?
See this StackOverflow answer regarding Go's type inference. I'm not familiar with Go myself but based on this answer it seems like a one-way "type deduction" (to borrow some C++ teminology). It means that if you have:
then the type of In contrast, most functional languages have type inference that uses all possible information within a module (or function, if the inference algorithm is local) to derive the type of the variables. Complicated inference algorithms (such as Hindley-Milner) often involve some form of type unification (a bit like solving equations) behind the scenes. For example, in Haskell, if you write:
then Haskell can infer the type not just
(The lowercase Here's a more interesting example: the fixed-point combinator that allows any recursive function to be defined:
Notice that nowhere have we specified the type of
This says that:
|
|||||||||
|
Type inference in Go is extremely limited and extremely simple. It works only in one language construct (variable declaration) and it simply takes the type of the right-hand side and uses it as the type for the variable on the left-hand side. Type inference in Haskell can be used everywhere, it can be used to infer the types for the whole program. It is based on unification, which means that (conceptually) all types are inferred "at once" and they can all influence each other: in Go, type information can only flow from the right-hand side of a variable declaration to the left-hand side, never in the other direction and never outside of a variable declaration; in Haskell, type information flows freely in all directions through the entire program. However, Haskell's type system is so powerful that type inference can actually fail to infer a type (or more precisely: restrictions have to be put in place so that a type can always be inferred). Go's type system is so simple (no subtyping, no parametric polymorphism) and its inference so limited that it always succeeds. |
|||||
|