I am a Haskell rookie and I often find myself having to decompose a data with pattern matching only to apply a function to one of its member and then reassemble it.
Say I have:
data Car = Car { gas :: Int, licensePlate :: String }
and I want it to halve its gas when it drives, and refuel it, I'm doing:
mapGas:: (Int -> Int) -> Car -> Car
mapGas f (Car aGas aLicensePlate) = Car (f aGas) aLicensePlate
drive:: Car -> Car
drive = mapGas (flip div 2)
refuel:: Int -> Car -> Car
refuel = mapGas . (+)
Is there a way to do just that without having to define the auxiliary function mapGas? Since it can become rather bothersome having to write a map function for every member of the data when it's made of many fields. I know it is possible to assign a value to one of the members with accessors:
runOutOfFuel:: Car -> Car
runOutOfFuel aCar = aCar { gas = 0 }
Is it possible to map a function with accessors too? if so, how?
lens
tutorials hackage.haskell.org/package/lens – OutsellmapGas f = (\car -> car {gas = f (gas car)})
. This at least avoids mentioning the other fields. – NaphthylmapGas f = (\car@Car{ gas = g } -> car {gas = f g })
. Longer, but you can see thegas
field on both sides of->
. – Atreus