The essential concept applies universally in some fashion, yes, but rarely in a useful manner.
To start with, from the type theory perspective this assumes, "dynamic" languages are best regarded as having a single type, which contains (among other things) metadata about the nature of the value the programmer sees, including what these dynamic languages would call a "type" themselves (which is not the same thing, conceptually). Any such proofs are likely to be uninteresting, so this concept is mostly relevant to languages with static type systems.
Additionally, many languages that allegedly have a "static type system" must be regarded as dynamic in practice, in this context, because they permit inspection and conversion of types at run-time. In particular, this means any language with built-in, by-default support for "reflection" or such. C#, for instance.
Haskell is unusual in how much information it expects a type to provide--in particular, functions cannot depend on any value other than the ones specified as its arguments. In a language with mutable global variables, on the other hand, any function can (potentially) inspect those values and change behavior accordingly. So a Haskell function with type A -> B
can be regarded as a miniature program proving that A
implies B
; an equivalent function in many other languages would only tell us that A
and whatever global state is in scope combined imply B
.
Note that while Haskell does have support for things like reflection and dynamic types, use of such features must be indicated in the type signature of a function; likewise for use of global state. Neither is available by default.
There are ways to break things in Haskell as well, e.g. by allowing runtime exceptions, or using non-standard primitive operations provided by the compiler, but those come with a strong expectation that they will only be used with full understanding in ways that won't damage the meaning of external code. In theory the same could be said of other languages, but in practice with most other languages it is both more difficult to accomplish things without "cheating", and less frowned-upon to "cheat". And of course in true "dynamic" languages the whole thing remains irrelevant.
The concept can be taken much further than it is in Haskell, as well.