Here is a very useful bash script to have lying around:
#!/usr/bin/env bash
shopt -s nullglob
while true; do
if [[ "$PWD" == "$HOME"
|| "$PWD" == /
|| -f "$PWD/package.yaml"
|| -f "$PWD/stack.yaml"
|| -n "$(echo -n ./*.cabal)" ]]; then
exec "$@"
else
cd ..
fi
done
Name this something like "run-in-project-root", and then you can prefix any command you run with "run-in-project-root" in order for it to run in the project's root, as defined by the existence of a package.yaml or stack.yaml or *.cabal file. (Of course you can customize the exact condition to your tastes.) So running "run-in-project-root fast-tags filename" is exactly like running "fast-tags filename" except that fast-tags will execute in the project root. (And the same for all the other shell commands that you run.)
Of course, this works both when running fast-tags (or any other command) directly in the shell, and when running a bash snippet in vim with :!, so long as the "run-in-project-root" script is in a directory that's in your $PATH.