0: There are plenty of places where not supplying a type annotation is more trouble than just writing it. Eg (Haskell since I'm not familiar with OCaml offhand):
data Foo = FooBar Int String
| FooBaz [Int]
I'm not even sure how to avoid writing explicit type annotations for Int, String, and [Int] there; maybe OCaml makes it easy, but I doubt I'd bother literally all but less than ten times.It does make it easy. OCaml has a full matrix of types:
- Nominal product types (records)
- Nominal sum types (variants)
- Structural product types (objects)
- Structural sum types (polymorphic variants)
You could actually always use structural types and never have to actually define types. But OCaml people actually really like the nominal types because their typing rules are stricter and easier for people to understand. But the structural types can come in really handy, e.g. they give you a very convenient way to encode data between libraries that don't need to know about each other. E.g. there is an effort to add JSON-structured output to the OCaml compiler itself. This is using a polymorphic variant type to represent the JSON data type, to avoid having a dependency on any particular JSON library, but still being compatible with popular OCaml JSON libraries ( https://ocaml-community.github.io/yojson/yojson/Yojson/index... ).
If you wanted to, you could use
Either (Int, String) [Int]
in your code and rely on type inference to do all the work.Not in Haskell as far as I know, but (assuming MonomorphismRestriction) there's no technical reason why
data Qwe = Q a
qwe_eps :: Qwe
qwe_eps = Q ""
couldn't infer a ~ String in the type definition for Qwe. It's just annoying and pointless, because you never actually care about having to write a explicit type annotation there. (Which was my point.) But it's still a explicit type annotation that you're required to write. (Which was (kind of) chrisseaton's point.)data Foo a b c = FooBar a b | FooBaz c
or
data Foo a b = FooBar a b | FooBaz [a]
But I agree that writing explicit type annotations is overall better practice.
quux :: a -> a
quux x = x
# quux takes any type genericly
frob y = y () ++ [()]
# frob takes some specific type, but we don't need to specify which (spoiler alert: it's () -> [()])
Edit: actually the type is generic (not polymorphic) as well.
I think their point is that they there were vanishingly few times where they were required to write explicit type annotations. As they say, mostly when dealing with data serialization. That doesn't say whether they wrote more, however.