Is there a shorthand way to update a specific struct field in racket?

前端 未结 3 1661
轮回少年
轮回少年 2021-02-12 23:30

Suppose I have a struct with many fields:

(struct my-struct (f1 f2 f3 f4))

If I am to return a new struct with f2 updated, I have

3条回答
  •  别跟我提以往
    2021-02-13 00:12

    Alexis's macro is fantastic, and Greg's rightly pointed out struct-copy and match+struct*, but since you specifically mentioned lenses in your example I'll point out that there is now a lens package for Racket (disclaimer: I wrote a lot of it). It provides struct/lens and define-struct-lenses macros for your use case:

    > (struct/lens foo (a b c))
    > (lens-view foo-a-lens (foo 1 2 3))
    1
    > (lens-set foo-a-lens (foo 1 2 3) 'a)
    (foo 'a 2 3)
    > (lens-transform foo-a-lens (foo 1 2 3) number->string)
    (foo "1" 2 3)
    

    define-struct-lenses lets you define the lenses seperately from the structs:

    > (struct foo (a b c))
    > (define-struct-lenses foo)
    

    The above is equivalent to (struct/lens foo (a b c)). If you're only operating on structs in isolation from other kinds of structs, using define-struct-updaters is simpler. But if you have a lot of nested data structures of various flavors, the ability to compose lenses makes them a powerful tool for the job.

提交回复
热议问题