To aid you in the latter task, you can press a key in your editor to fetch an automatically-inferred type for the name under the cursor and insert it into your code, then refine it as necessary if you find it to be too general (inference always gives the most general type possible).
[1] https://github.com/DanielG/ghc-mod
Ghcide is on my list to try next as it's gotten a lot of attention lately.
If you're talking about exhaustiveness checks, you can disable those and use `-fdefer-type-errors` to compile programs which don't type-check.
Although I will say that most of the time when you have a Maybe instance that you know is Just, it means you're branching in the wrong part of your program.
Right, but if you were using, say, Idris, the program would type check. It's just that Haskell's type system is too weak. Disabling type checking is not what the question was about. The program is type-correct, yet not in Haskell's particular system.
> Although I will say that most of the time when you have a Maybe instance that you know is Just, it means you're branching in the wrong part of your program.
Perhaps, but that doesn't change the fact that if you write it in some way that is perfectly correct, Haskell's particular type system will still not accept your program.
How many systems have you prototyped in Haskell?
That's very much my experience, as well. Assuming - and it's a very big assumption - that your use case has equivalent library support.
After typechecking it leaves provisional stubs in .pytype/pyi/, and it has a tool to merge them into the original code.
mypy has stubgen: https://mypy.readthedocs.io/en/latest/stubgen.html
As far as I know it's less powerful since mypy isn't really built for unannotated code and pytype is.
But a large refactor on a large project is still a pain. By the time you get there, you still want your model stable and/or flexible enough that you don't need to do that much.
On a small enough project, every refactor is easy enough that you can lean into it. Make a bunch of assumptions you're not confident about, setting up the types so you're sure you'll know what needs fixing when they're wrong. Then you test those assumptions as you write - and run - more code.
A full rebuttal of this blog post would take much longer, but suffice to say inference does the exact opposite of what they are claiming; it increases readability and usability.
A few human-subjects studies from different labs have recently been ran on this and the findings mostly agree with my opinions. Papers forthcoming.
edit: In Haskell it goes beyond just locally inferring variables, it enables a new type of development with typed holes that feels more like a back and forth conversation with the compiler. I don't see how "I can leave the types off my C# variables" has anything to do with that.
Also, if lack of type annotations were a common problem, you would expect Java programmers who switch to Python to frequently want to annotate all their types. But as far as I know this is not the case: even now that mypy is becoming popular, people only annotate the types that it can't infer.
But how would companies/people know if it damaged readability? There has been little research on this (a few studies are currently in peer review!) and our intuition about such things is often inaccurate. There are so many other confounding factors that it is hard to isolate just type inference/annotations.
That's a language that historically has not had type inference. Any examples of companies mandating type annotations in historically type-inferred languages?
In languages with even reasonably good type inference you'll find that the idiom is not to annotate types at the very least inside function bodies. And in OCaml, which has principality of type inference i.e. the types it infers cannot be overridden and corrected by manual annotation, the idiom is to not annotate implementation files at all.
You talk about cognitive load of looking up type info but there's also a cognitive load to having to parse every type annotation over and over again whenever you read the code. And since code is read more often than it's written, that's really just optimizing for the wrong load. As you re-read a codebase over time you'll get familiar with its types. And then the annotations start to get in the way. This is in fact one of the reasons people prefer dynamic typing.
> My response? Go refactor your hideous code.
To what? Would be very interesting to see your suggested refactor of that code.
> Before every language designer blindly accepts type inference as a good thing, I propose that some research be conducted.
What would be the research question(s) specifically?
Type inference, as others have suggested, does not do what you want. If your program is well-typed according to a particular type system which you must have in mind while writing the program, they'll save you from writing explicit type annotations, but they cannot come up with "correct" type for a correct program that's not written for that particular type system.