[] is not a constraint and it never will be. In Haskell, every type has a kind, which is kind of like a type of type. It's one level up.
Things like [Int], String, and Double -> Double are concrete types. We say they have kind Type. Something like [] or Maybe has kind Type -> Type; it takes a type as argument and then produces a type itself.
On the other hand, something like Functor is fundamentally different. Functor has kind
Functor :: (Type -> Type) -> Constraint
So, first off, it takes a parameterized type, like [] or Maybe as argument. But even once it does so, it produces a Constraint, a fundamentally different thing than a Type. Now, when we write a type signature
j :: (Enum a) => [] a -> [] a
The things on the left of the => are always constraints and the thing on the right of the => is always a Type. It makes no more sense to put [] a on the left-hand side of => than it does to put Functor a on the right-hand side.
It sounds like the thing you're trying to express is "this thing has to be a list", in which case either of the following will suffice
j :: (Enum a) => [a] -> [a]
j :: (Enum a) => [] a -> [] a
the two are equivalent but the former is much more idiomatic. If you come along later and decide "oh wait, I can make this work for any functor, you can change the type signature to
j :: (Enum a, Functor f) => f a -> f a
And this won't break any of the code that's calling j, as any code that was calling it with a list before will still be calling it with a valid Functor instance.
Note: You'll see some old literature that refers to the kind *. Some literature (and even GHC in some places) will say that Maybe has kind * -> *. For these purposes, * is equivalent to Type. Being able to refer to Type as * is an unfortunate historical quirk and complicates the Haskell parser (is Foo * Int equivalent to Foo Type Int or is it multiplication like (*) Foo Int?), so the general recommendation nowadays is to use Type to refer to the kind of types.