In high level statically typed functional languages like Haskell or OCaml, the type system is used canonically to enforce constraints on the types of entities being modelled in some problem domain.
From a software engineering point of view, are there any practical benefits to such type systems beyond simply enforcing constraints? For example can they make reasoning about the problem domain easier? Can they make design abstractions more flexible/robust in the face of changing requirements? Can they help manage the complexity in large systems? etc...
And if such benefits do exist, can we somehow try to replicate them in dynamic languages such as Ruby, Python or Clojure?