As as far as I know, I can create patterns with conditions attached to them, like
f[x_Integer] := x
With this function I would expect something like this
Out:={2, 1.5}
Did Mathematica use any type-inference system? or just evaluated the condition and then apply his rules, if that’s the case, there are any difference between f[x_Integer] := x and f[x_ ? IntegerQ] := x
Those two definition are very similar, but the evaluation path is different, and there are cases when the outputs are different. One situation I have thought is when the function has the attribute HoldAll. The pattern x_Integer will not make any evaluation of x before deciding whether it has the head Integer, while the pattern x_?IntegerQ will evaluate IntegerQ[x], which can lead to a different answer: