Overloading a struct constructor?

后端 未结 2 1406
死守一世寂寞
死守一世寂寞 2021-01-19 19:36

My question is the same as the one asked here, but the answer given there doesn\'t actually work.

I have a bunch of structs inheriting from a parent struct A

2条回答
  •  独厮守ぢ
    2021-01-19 20:09

    The struct construct will define two entities with the name of the struct. A constructor and a transformer binding that has information on the struct.

    In order to avoid the "duplicate identifier" error you can use #:omit-define-syntaxes.

    An alternative is to define the struct in a submodule and export only the things you need (and possibly renaming some of the identifiers).

    #lang racket
    (struct horse (color)
      #:constructor-name make-horse
      #:omit-define-syntaxes
      #:transparent)
    
    (define (horse #:color [color "black"])
      (make-horse color))
    
    (horse)
    (horse #:color "red")
    

    Output:

    (horse "black")
    (horse "red")
    

    EDIT

    A solution that works with match is possible with the help of a match expander. Note: You need at least version 6.5 for this to work due the the use of #:extra-name.

    #lang racket
    
    (module horse racket
      (provide (struct-out Horse)
               make-horse)
      (struct horse (color)
        #:extra-name Horse
        #:extra-constructor-name make-horse
        #:transparent))
    
    (require 'horse)
    
    ; the custom horse constructor
    (define (my-make-horse #:color [color "black"])
      (make-horse color))
    
    (define-match-expander horse
      ; match expander
      (λ (pat)
        (syntax-case pat ()
          [(_horse more ...)
           #'(Horse more ...)]))
      ; constructor
      (λ (stx)
        (syntax-case stx ()
          [(_horse arg ...)
           (syntax/loc stx
             (my-make-horse arg ...))])))
    
    (horse)
    (horse #:color "red")
    
    (match (horse #:color "blue")
      [(horse color) color])
    

    Output:

    (horse "black")
    (horse "red")
    "blue"
    

提交回复
热议问题