Here's a first cut at a module that you can import into BSL programs.
The least obvious part is defining a new `define-type' and `type-case'
that invents hidden names for the variants and them maps between them
while expanding to the original forms.
----------------------------------------
#lang racket/base
(require plai/datatype
lang/prim
(prefix-in beginner: lang/htdp-beginner)
(for-syntax racket/base
syntax/boundmap))
(provide (rename-out
[my-define-type define-type]
[my-type-case type-case]))
(define-for-syntax variants (make-free-identifier-mapping))
(define-for-syntax (record-variants! vars x-vars)
(for ([var (in-list vars)]
[x-var (in-list x-vars)])
(free-identifier-mapping-put! variants var x-var)))
(define-syntax (my-define-type stx)
(syntax-case stx ()
[(_ ty [var (fld ctc) ...] ...)
(with-syntax ([(x-var ...)
(map (lambda (s)
(datum->syntax
s
(string->uninterned-symbol
(symbol->string (syntax-e s)))
s
s))
(syntax->list #'(var ...)))])
(define (adjust new-stx)
;; `define-type' seems to use the context of the
;; form for `ty?', so copy over old context
(datum->syntax stx (syntax-e new-stx) stx stx))
#`(begin
#,(adjust
#'(define-type ty
[x-var (fld (first-order->higher-order ctc)) ...]
...))
(beginner:define (var fld ...)
(x-var fld ...))
...
(begin-for-syntax
(record-variants! (list #'var ...) (list #'x-var ...)))))]))
(define-syntax (my-type-case stx)
(syntax-case stx ()
[(_ Ty e [var (id ...) rhs] ...)
(with-syntax ([(x-var ...)
(map (lambda (var)
(or (free-identifier-mapping-get
variants
var
(lambda ()
(raise-syntax-error
#f
"not a variant name"
stx
var)))))
(syntax->list #'(var ...)))])
#`(type-case Ty e [x-var (id ...) rhs] ...))]))