{"size": 2422, "ext": "scrbl", "max_stars_repo_path": "lens-doc/unstable/lens/struct-nested.scrbl", "max_stars_repo_name": "AlexKnauth/lens", "max_stars_repo_stars_event_min_datetime": "2015-07-08T12:56:46.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-17T21:21:54.000Z", "max_issues_repo_path": "lens-doc/unstable/lens/struct-nested.scrbl", "max_issues_repo_name": "AlexKnauth/lens", "max_issues_repo_issues_event_min_datetime": "2015-07-07T01:47:59.000Z", "max_issues_repo_issues_event_max_datetime": "2019-09-10T18:35:17.000Z", "max_forks_repo_path": "lens-doc/unstable/lens/struct-nested.scrbl", "max_forks_repo_name": "AlexKnauth/lens", "max_forks_repo_forks_event_min_datetime": "2015-07-07T05:01:29.000Z", "max_forks_repo_forks_event_max_datetime": "2019-07-16T00:37:04.000Z"}
{"max_stars_count": 66, "max_issues_count": 199, "max_forks_count": 11, "avg_line_length": 39.064516129, "max_line_length": 79, "alphanum_fraction": 0.6969446738}
#lang scribble/manual

@(require lens/private/doc-util/main)

@title{Nested struct lenses}

@(persistent-lens-unstable-examples struct-nested-examples)

@defform[#:id struct-nested-lens
         (struct-nested-lens [struct-id field-id] ...)]{
  Constructs a lens that views nested structures. Each @racket[struct-id] and
  @racket[field-id] pair is paired into a lens for viewing that field of that
  struct, then the list of lenses are @racket[lens-thrush]ed together.

  For example, given a complicated nested tree of state representing a game:
  @struct-nested-examples[
    (struct game (player level) #:transparent)
    (struct player (posn stats) #:transparent)
    (struct posn (x y) #:transparent)
    (struct combat-stats (health attack) #:transparent)
    (define the-game (game (player (posn 0 0) (combat-stats 10 1)) 'foo-level))
    the-game
  ]

  We can create a lens for traversing the nested structures of the game state.
  At each step, we provide the name of the struct we're examining and the name
  of the field we wish to traverse into.
  @struct-nested-examples[
    (define game-player-health-lens
      (struct-nested-lens [game player]
                          [player stats]
                          [combat-stats health]))
    (lens-view game-player-health-lens the-game)
    (lens-set game-player-health-lens the-game 20)
]}

@(persistent-lens-unstable-examples struct-nested*-examples)

@defform[#:id struct-nested-lens*
         (struct-nested-lens* struct-id both-id ... field-id)]{
  Like @racket[struct-nested-lens], but for the case where each nested
  field is named the same as its struct type. For example, given the
  game state defined in the examples for @racket[struct-nested-lens]:
  @struct-nested*-examples[
    (struct game (player level) #:transparent)
    (struct player (posn stats) #:transparent)
    (struct posn (x y) #:transparent)
    (struct combat-stats (health attack) #:transparent)
    (define the-game (game (player (posn 0 0) (combat-stats 10 1)) 'foo-level))
    the-game
  ]

  Because each field is named the same as its struct type, we can
  create a lens for viewing the player's x coordinate more succinctly
  than with @racket[struct-nested-examples]:
  @struct-nested*-examples[
    (define game-player-x-lens
      (struct-nested-lens* game player posn x))
    (lens-view game-player-x-lens the-game)
    (lens-set game-player-x-lens the-game 5)
]}
