We perceive color based in part by how our cone cells react to the wavelengths of light and how those reactions are multiplexed with each other in being propagated to the brain. The three cone cells are commonly called “red”, “green”, and “blue” but this gives an incorrect impression, because the “red” cell actually reacts most strongly to yellow light. It’s better to call them L, M, and S, for the long, medium, and short wavelengths that they respond to. Their reactions to light can then be thought of (I’m simplifying) as if they were multiplexed into three signals: luminance, green versus yellow, and blue versus yellow.
For violet light (see here) we see a low luminance signal, a neutral green versus yellow signal, and a positive blue versus yellow signal. For blue, we see a moderate luminance signal, a positive green versus yellow signal, and a positive blue versus yellow signal. For red, we see a high luminance signal, a negative green versus yellow signal, and a negative blue versus yellow signal. Finally, for white we see a high luminance signal, a neutral green versus yellow signal, and a neutral blue versus yellow signal.
If you work out the math, it turns out that the signals sent for violet + dark grey = dark red + blue. Since dark red + blue = purple, and since we consider dark grey to be color-neutral, we equate violet with purple.