Haskell, modyfying only one field of structure


I have a some structure:

data S = { 
  a :: Integer,
  b :: Integer,
  c :: String,
  d :: Map String Integer

I closed it in my State monad, And I am using it in following way:

s <- get
let S {a = a', b =b', c=c', d=d'} s   
put $ S {a = a' + 1, b = b', c= c', d = d'}   

As you can see, when I would like to modify/read only one field (here a), I must get and put all fields - it is embarassing - otherwise I get warnings and sometimes runtime errors.

Can you try to propose me some solution to make it better and cleaner ?

Thanks in advance,

Show source
| haskell   2017-01-06 08:01 1 Answers

Answers ( 1 )

  1. 2017-01-06 08:01

    You can use a record update and specify only the fields you want to update. Also, you can extract a particular field during pattern matching.

    s@S{ a = a' } <- get 
    put $ s{ a = a' + 1 } 

    Alternately, if you find yourself doing a lot of this sort of thing, you might want to use lens. With lens, you would have to make lenses for S (which requires turning on -XTemplateHaskell)

    data S = { _a, _b :: Integer, _c :: String, _d :: Map String Integer }
    makeLenses ''S

    But then, in your state monad you can just write

    a += 1

    Yep, this is legitimate Haskell. += is actually a thing.

◀ Go back