I see now that Racket has types. At first glance it seems to be almost identical to Haskell typing. But is Lisp's CLOS covering some of the space Haskell types cover? Creating a very strict Haskell type and an object in any OO language seems vaguely similar. It's just that I've drunk some of the Haskell kool-aid and I'm totally paranoid that if I go down the Lisp road, I'll be screwed due to dynamic typing.
CL type system is more expressive than the Haskell one, e.g., you can have a type
However, Lisp compilers does not force their understanding of type safety down your throat, so you can ignore their "notes" - at your own risk.
This means that you can write Haskell in Lisp (so to speak) by declaring all value types and carefully making sure that all the necessary types are inferred, but then it is easier to use Haskell in the first place.
Basically, if you want strong static typing, use Haskell or OCaml, if you want strong dynamic typing, use Lisp. If you want weak static typing, use C, if you want weak dynamic typing, use Perl/Python. Each path has its advantages (and zealots) and disadvantages (and detractors), so you will benefit from learning all of them.
Typed Racket is very different from Haskell. Type systems in Lisp and Scheme, and indeed type systems in traditionally untyped language ecosystems in general, have a fundamental goal that other type systems do not - interoperating with existing untyped code. Typed Racket for example introduced whole new typing rules to accommodate various Racket idioms. Consider this function:
For non-empty lists, this returns the first element. For empty lists, this returns false. This is common in untyped languages; a typed language would use some wrapper type like
A gradual type system must provide tools for dealing with common untyped idioms and interacting with existing untyped code. Using it will be quite painful otherwise, see "Why we're no longer using Core.typed" for a Clojure example.