Is it possible to pattern match by function in Haskell?
No. It is one of the consequences of Rice's theorem [wiki] that it is impossible to determine in general if two functions are equivalent. This thus means that it is possible to construct a function that can add two numbers together, but it is impossible for the compiler to proof that that function is equivalent to (+).
If we would use reference equality, then \x y -> x + y should not match with the pattern whereas passing (+) directly would match. This would be rather bizar. Imagine that you have a function f 0 = abs, or f 0 x = abs x. It would be quite strange that a (small) implementation detail of a function could determine the behavior of another function.
The function definition is hower correct (tested this on a GHC 9.0.1 and 8.6.5). It however will not check if the function is (+): you define a variable named (+) that you can use in the body of the function. You can use it as an infix operator, like x + y, or as (+) x y. But the function definition is identical to:
foo :: (a -> a -> b) -> a -> a -> b
foo g x y = g x y
or
foo :: (a -> a -> b) -> a -> a -> b
foo g x y = x `g` y
If you turn the -Wname-shadowing warning on, it will throw a warning that you have a temporary variable that clashes with a variable from a context above:
ghci> f (+) x y = x + y
<interactive>:1:3: warning: [-Wname-shadowing]
This binding for ‘+’ shadows the existing binding
imported from ‘Prelude’ (and originally defined in ‘GHC.Num’)
The signature of your function probably causes that much errors, the signature here should be:
f :: (a -> b -> c) -> a -> b -> c
f (+) x y = x + y
but again, this will not match with the (+) function defined in the Prelude.
If you need some parameter to determine a function, you can - as @RobinZigmond says - make a type that represents certain functions, for example:
data FunctionSelector = Add | Sub
foo :: Num a => FunctionSelector -> a -> a -> a
foo Add = (+)
foo Sub = (-)