"But I know of no scientific studies actually backing up the (sometimes implicit) claim that this types-first methodology leads to better languages, from the point of view programmer productivity."<p>So here's my problem, maybe I am using Haskell wrong, and somebody can give a good answer (FYI - I am big fan of Haskell, but I am still much more efficient in Python).<p>Let's say I write a library, I annotate all the functions with types, so I give it a nice API, and then what happens.. I realize I should have used a different type for this parameter in this library. For instance, a type class instead of normal type. But boy, it's like everywhere. Or it's a third party library and I can't really change the type signatures. I just wish sometimes that I could just "forget" the types temporarily and just borrow the existing logic, and then reintroduce different types, type check, done.<p>To be fair, Haskell has potential solution for this type of problem - type inference. But the thing is, once you write the (expected) type signatures into your program (which is sometimes needed to actually help the type inference, and it's also useful as a documentation), they are always there, and sometimes, they obstruct.<p>So I guess I wish there was a tool with which I could manage type information in the program in a lot more dynamic way than I currently do. That would, IMHO, close the gap to the dynamic languages.<p>What about making every type into a type class, would it do the trick? But how would the concrete type be specified, then? Would the compiler pick it?<p>(Maybe it's obvious, but let me point out the connection of this question to lambda calculus. I can have two functions in typed lambda calculus which are different, because they have different type signatures, but their actual semantics is identical (provided they get arguments of correct type); or in other words, if we convert both into untyped lambda calculus, we get identical functions. So the question is, why cannot we somehow reuse code from the first function, why we have to define the same code twice with different type signature?)