Pattern matching 'Some' and 'None'

I am porting SML to Racket. Managed to create a recursive data type like this. I reuse a macro by Alexis King for this.

(define-datatype Expr
  ( BoolValue Boolean  )
  ( IntValue  Number )
  ( Op  Expr (U Plus GTEQ) Expr)
  ( If  Expr Expr Expr)
  ( Assign  String Expr)
  ( Deref String)
  ( Seq Expr Expr)
  ( While Expr Expr)

I also have

(struct None ()
(struct (i) Some ([v : I])
(define-type (Opt a) (U None (Some a)))

After this I tried to match some patterns but couldn't proceed beyond a point. I suspect syntax is the major issue. Could you take a look ?
This is part of a longer method and I match all the Expr. Error will show identifiers are unbound at this stage. No other error but there are malformed braces. I suspect.

I believe the pattern isn't generally specified as per the type annotation.

(: reduce ((Opt (Expr (Listof Store) ))->
                                 (Opt (Expr (Listof  Store )))))

(define (reduce expr store )
  (match expr
    [  Some (( Op  (? integer? n1) Plus (? integer? n2)) store )  Some ( (IntValue (+ n1  n2)) store)]
    [  Some (( Op  (? integer? n1) GTEQ (? integer? n2)) store )  Some ( (BoolValue (>=  n1  n2)) store)]

    [  Some (Op  (? integer? n1) Skip (? boolean? n2)) store
             (match  (reduce  n2 store)
               [ Some  (IntValue nn2) store  (Some ((Op n1 Skip nn2) store))]
               [ (None)  (None) ]
             (match  (reduce  n1 store)
               [ Some   (IntValue nn1) store  (Some ((Op nn1 Skip n2) store))]
               [ (None)  (None) ]
    [ Some(IntValue n ) store (None)]
    [ Some (If e1 e2 e3) store
             (match e1
               [#t  Some e2 store  ]
               [#f  Some e3 store ]
               [_   (match (reduce e1 store )
                      [Some  (IntValue ee1) store  (Some  ((If ee1 e2 e3) store  ))]
                      [ (None)  (None) ]

I also have code that doesn't show compiler errors (e.g)

(: printexpr (Expr -> String))
(define (printexpr expr)
  (match expr
    [(IntValue n) (string-append (format  "~a" n))]
    [(BoolValue b) (string-append (format  "~a" b))]
    [(Deref l)  (string-append (format "( ~a ~a )" "!"  l))]
    [( Op e1 operate e2  )
            (string-append (format "( ~a ~c ~a)"  (printexpr e1)  (operator operate)
            (printexpr e2 )))]
        [ (Seq e1 e2 )   (string-append (format " ~a ;  ~a" (printexpr e1 )
                                      (printexpr e2)))]
    [ (While  e1 e2 ) (string-append  (format "while ~a do ~a " (printexpr e1 )
                                          (printexpr e2)))]


You need to read about the pattern matcher. Especially how patterns look for structures.

In your concrete case of Some you have a constructor named Some
and have only one field. So pattern to match any Some struct is:

(Some v)

If the value v needs to of a certain type, then replace v with a pattern to match
the type you need.

But, read the section on match in the Guide.

Looks like the same issues as in your now-deleted post on Stack Overflow about this. Same advice: Read up on match and how to match structures with it.

Also need a better grasp on how Lispy languages like Racket works; a lot of that looks like copy & pasted SML code maybe with some extra parenthesis added here and there. Which isn't how it works at all. Maybe start with simpler projects (And forget Typed Racket for the moment) to get more comfortable with the language?

After a few iterations it compiled when I carefully checked all the types. DrRacket's debugging mechanism also helped.Doom Emacs seems to have debugging support too but I am not using LSP/DAP etc. Mainly it was about patterns, types and unbound identifiers.

ADTs and the reusable macro helped.