Functional programming is great fun. Purely functional code doesn't need to be run however as it doesn't do anything.
The only way to really do something is with side effects.
Once you have interaction in any way with the real world, you can do basically anything given you have control over the environment your code is run in.
Imagine a programming language that allows you to only exchange strings with the real world, you could encode all actions that should be taken on behalf of the program in strings and execute them for it in your runtime.
I felt like the IO Monad in Haskell was a mind bending concept, until I rediscovered the Common Gateway Interface, sparked by a debate with a coworker on how to implement webservices in COBOL [0]. Having done CGI Scripts a long time ago, it always felt more like a hack than a beautiful mathematical idea.
So my takeaway is that by not even relying on opening a port, but just communicating through STDIN & STDOUT you could further simplify web development
After all, setting up the socket is just boilerplate for getting your (String -> String) -> IO ()
function in place.