Search code examples
frege

How can I "set" a field in a record in Frege?


suppose I have these records:

data Group = Group { id :: Id, name :: Name }
derive Show Group

data Game = Game { world :: World, groups :: [Group], random :: FRandom }
derive Show Game

I would like to add a new group to game, but I would like to avoid calling the Game constructor because if later I add a field to game I do not want to change all the Game constructor invokations. Suppose I want to add a new group to an instance of game. What is the best way to do it?


Solution

  • This is easy.

    Given:

    game = Game { .... }   -- some game
    newgroup = Group { .... } -- some new group
    

    you simply say:

    game' = game.{groups <- (newgroup:)}
    

    Spelled out:

    Build a new game' from game, but change the groups field, by applying the (newgroup:) function to the old group value. This, of course, cons'es newgroup to the front of the previously existing groups, ence it is equivalent to:

    ng = newgroup : game.groups
    game' = game.{groups = ng}
    

    Marimuthu has a nice blog post about just this here: http://mmhelloworld.github.io/blog/2014/03/15/frege-record-accessors-and-mutators/

    Your decision not to use the Game constructor is a very wise one. In fact, what I do in such cases is to create a "default" value, and make a new one from the default with this:

    rec.{name = value, another <- function, ...} 
    

    syntax.