Search code examples
structschemeracketrecursive-type

How do I define a recursive struct in Racket?


I'm trying to imitate recursive types in OCaml in untyped Racket, but I can't seem to find documentation on defining recursive structs. How would I go about mapping this:

type example =
| Red
| Blue of example
| Yellow of example * example;;

into something in Racket?

I've tried the following:

(struct Red ())
(struct Blue (e1))
(struct Yellow (e1 e2))
(struct example/c
    (or/c (Red)
          (Blue example/c)
          (Yellow example/c example/c)))

However, it doesn't work as expected when I put example/c in a contract, because it claims it's a procedure. Any help?


Solution

  • I have changed the example. Here is an example where the variable e has the contract example/c.

    #lang racket
    
    (struct Red     ()      #:transparent)
    (struct Blue    (e1)    #:transparent)
    (struct Yellow  (e1 e2) #:transparent)
    
    (define example/c
      (flat-murec-contract ([red/c     (struct/c Red)]
                            [blue/c    (struct/c Blue   example/c)]
                            [yellow/c  (struct/c Yellow example/c example/c)]
                            [example/c (or/c red/c blue/c yellow/c)])
                           example/c))
    
    
    (define r (Red))
    (define b (Blue r))
    (define y (Yellow r b))
    (define e y)
    
    (provide (contract-out [e example/c]))
    
    (match e
      [(Red)          (list "Red")]
      [(Blue   e1)    (list "Blue" e1)]
      [(Yellow e1 e2) (list "Yellow" e1 e2)]
      [else           "huh"])
    

    If you change, say, (Yellow r b) to (Yellow r 42) then you get an error.