run itself can't do that. you need to use runSettings:
The Settings parameter you want to pass it contains the information about the hosts it listens on.
The relevant type here is HostPreference. Although it allows you to specify different wildcards, including IPv6Only, we'll use the Host constructor here.
Based on this answer, I'll show a minimal example to listen on localhost only.
Note that accessors like settingsHost are marked deprecated, but the official documentation for warp 2.1.2.1 still shows an example using settingsTimeout here.
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai (responseLBS)
import Network.Wai.Handler.Warp
import Network.HTTP.Types (status200)
import Network.HTTP.Types.Header (hContentType)
main = do
let port = 3000
putStrLn $ "Listening on port " ++ show port
let settings = defaultSettings { settingsPort = port,
settingsHost = Host "127.0.0.1" }
runSettings settings app
app req = return $
responseLBS status200 [(hContentType, "text/plain")] "Hello world!"