[plt-scheme] Typed Scheme and match with struct patterns

From: Sam TH (samth at ccs.neu.edu)
Date: Tue Mar 24 13:33:02 EDT 2009

On Tue, Mar 24, 2009 at 2:09 AM, Paulo J. Matos <pocmatos at gmail.com> wrote:
> Check the following program:
> #lang typed-scheme
> (require scheme/match)
> (define-type-alias mytypes (U foobar foo bar))
> (define-struct: foobar
>  ((useless : Integer)))
> (define-struct: foo
>  ((name : Symbol)))
> (define-struct: (bar foo)
>  ((val : String)))
> (: match-bug (mytypes -> Void))
> (define (match-bug f)
>  (match f
>    ((struct foobar (i))
>     (display i))
>    ((struct foo _)
>     (printf "Name : ~a\n" (foo-name f))
>     (when (bar? f)
>       (printf "Val : ~a\n" (bar-val f))))))
> Running it returns:
> typecheck: Wrong function argument type, expected foo, got mytypes for
> argument 1 in: f
> even though it is pretty obvious f in that case is a foo.

What doesn't work here is just using the `struct' pattern as a
predicate, instead of actually matching on the fields.  If you're
using `match', it unfortunately doesn't give you any information (that
TS understands) about the originally matched expression.  This is
something I hope to address eventually.  But the right way to write
this code is:

(: match-bug (mytypes -> Void))
(define (match-bug f)
 (match f
  [(struct foobar (i))
   (display i)]
  [(struct foo (n))
   (printf "Name : ~a\n" n)
   (when (bar? f)
     (printf "Val : ~a\n" (bar-val f)))]))

which I think is clearer anyway.
sam th
samth at ccs.neu.edu

Posted on the users mailing list.