For example, in Python, if I have two functions that implement a "download" operation, but they accept different types of locations, I could use different modules to implement them:
from mypkg.endpoints import ftp
from mypkg.endpoints import http
ftp.download(ftp.info(some_ftp_info))
http.download(http.info(some_http_info))
You can see that we pass the result of `ftp.info` to each, which is essentially defining its type somewhat reliably.In OO, you can simplify things a great deal by encapsulating data in an object, as well as organizing functionality accordingly. I think (in Python at least) the same benefit can be accomplished by using modules for namespaces and grouping, like you would a class.
By using modules in this way, it is then possible to utilize types like you might in haskell as well as enforce immutability, assuming the "types" you create are immutable (like namedtuples).
All that said, I've yet to have the courage to enforce this sort of paradigm in a project. I worry that it would be prohibitively expensive to my fellow developers who may not appreciate the benefits. With that said, I would be interested if the paradigm would be reasonable over time.