[racket] prop:procedure and arity
On Feb 9, 2015, at 7:46 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> At Mon, 9 Feb 2015 19:36:56 -0500, "Alexander D. Knauth" wrote:
>> Say I want a struct that will act as a procedure.
>> For a given instance of that struct, I want the procedure to have a given
>> arity, but I don’t want the procedure to be a field in the struct.
>> Is there a way to do this without making the procedure a field?
>
> I think there's no way to do that, assuming that you want a single
> constructor that answers #t to `struct-constructor-procedure?`.
>
> If you get to substitute a function for the constructor, then you could
> make that function use `procedure-reduce-arity` on each raw instance,
> or you could generate a structure subtype for each arity and
> instantiate a subtype based on field values.
Ok sorry I missed this the first time I read this.
This works fine, thanks!
#lang racket
(require rackunit)
(struct my-f (lst) #:transparent)
(define (make-my-f lst #:name [name 'my-f])
(struct my-f2 my-f () #:transparent
#:property prop:procedure
(procedure-reduce-arity
(procedure-rename
(lambda (this . args)
(apply-my-f this args))
name)
(add1 (length lst))))
(my-f2 lst))
(define (apply-my-f my-f args)
(define lst (my-f-lst my-f))
(unless (= (length args) (length lst))
(error 'my-f "wrong number of arguments, expected ~v, recieved ~v" (length lst) args))
(for/sum ([x (in-list args)]
[a (in-list lst)])
(* a x)))
(define f (make-my-f '(1 2 3)))
(check-pred my-f? f)
(check-equal? (procedure-arity f) 3)
(check-equal? (f 3 2 1) 10)