There are a lot of other Haskell features you can use. Term-level recursion works:
f :: a -> b
f = f
Type-level recursion works, even without explicit term-level recursion:
data T a b = C (T a b -> (a -> b))
q :: T a b -> (T a b -> (a -> b))
q (C f) = f
w :: T a b -> (a -> b)
w x = (q x) x
f :: a -> b
f = w (C w)
This is basically encoding Russell's paradox at the type level. You can write out f explicitly, just so that it doesn't look like you might somehow still be applying w to itself recursively:
g :: a -> b
g = (\x -> ((\(C f) -> f) x) x) (C (\x -> ((\(C f) -> f) x) x))
There are even ways of doing this using highly impredicative definitions involving GADTs and type families, without involving any explicit recursion at all: