The reason why you can't do this is because in Haskell, records are inherently second class. They always must be wrapped in a constructor. So in order to have this work as intended you either must use an individual case for each constructor, or use a record substitute.
One possible solution is to use lenses. I'll use the implementation of lenses lens
since lens-family-th
doesn't seem to handle duplicate field names.
import Control.Lens
data Foo = A {_f :: Int}
| B {_f :: Int}
deriving Show
makeLenses ''Foo
foo :: Foo -> Foo
foo = f %~ (+1)
And then we can use it like this
> foo (A 1)
A{_f = 1}