lambdas 在用户定义的宏中抛出错误
lambdas throwing error inside a user defined macro
我定义了下面的宏...
(define-syntax >> ;;compose
(syntax-rules ()
[(>> f1 [args ...])
(lambda (x) (f1 args ... x))]
[(>> f1 [args1 ...] f2 [args2 ...] rf ...)
(>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]
[(>> f1 [args1 ...] f2 rf ...)
(>> (lambda (x) (f2 (f1 args1 ... x)) ) rf ...)]
[(>> f1 f2 [args2 ...] rf ...)
(>> (lambda (x) (f2 args2 ... (f1 x)) ) rf ...)]
[(>> f1 )
(lambda (x) (f1 x))]
[(>> f1 f2 rf ...)
(>> (lambda (x) (f2 (f1 x))) rf ...)]))
帮助我以这种方式编写函数:
(define composed-function (>> (lambda (x) (+ x 1)) (lambda (x) (+ x 1))))
问题是,命名函数一切正常,但是当我使用上面示例中描述的 lambda 时,我收到类似“lambda:lambda 中的错误语法”的错误,知道为什么会这样发生了什么?
问题是您的宏陷入了错误的模式。你认为应该应用这个:
[(>> f1 f2 rf ...)
(>> (lambda (x) (f2 (f1 x))) rf ...)]))
但实际上它实际上可以匹配这个模式:
[(>> f1 [args ...])
(lambda (x) (f1 args ... x))]
与 f1
匹配 (lambda (x) (+ x 1))
,(args ...)
匹配 (lambda (x) x)
。扩展为:
(lambda (x) ((lambda (x) (+ x 1)) lambda (x) x x))
这是胡言乱语。您可能最好使用需要在每个参数周围加上括号的模式:
(define-syntax >> ;;compose
(syntax-rules ()
[(>> (f1 args ...))
(lambda (x) (f1 args ... x))]
[(>> (f1 args1 ...) (f2 args2 ...) rf ...)
(>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]))
这也减少了您需要的参数数量。要使用它,请执行:
(define composed-function (>> ((lambda (x) (+ x 1))) ((lambda (x) (+ x 1)))))
当然,第三种选择就是使用racket/base
中的compose
。不可否认,它不允许您为每个函数传递固定参数,但您仍然可以通过 eta-expansion 获得它。
要使用 compose
,您的示例将如下所示:
(define composed-function (compose (lambda (x) (+ x 1)) (lambda (x) (+ x 1))))
(请注意,尽管函数与您的示例相反。)
我定义了下面的宏...
(define-syntax >> ;;compose
(syntax-rules ()
[(>> f1 [args ...])
(lambda (x) (f1 args ... x))]
[(>> f1 [args1 ...] f2 [args2 ...] rf ...)
(>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]
[(>> f1 [args1 ...] f2 rf ...)
(>> (lambda (x) (f2 (f1 args1 ... x)) ) rf ...)]
[(>> f1 f2 [args2 ...] rf ...)
(>> (lambda (x) (f2 args2 ... (f1 x)) ) rf ...)]
[(>> f1 )
(lambda (x) (f1 x))]
[(>> f1 f2 rf ...)
(>> (lambda (x) (f2 (f1 x))) rf ...)]))
帮助我以这种方式编写函数:
(define composed-function (>> (lambda (x) (+ x 1)) (lambda (x) (+ x 1))))
问题是,命名函数一切正常,但是当我使用上面示例中描述的 lambda 时,我收到类似“lambda:lambda 中的错误语法”的错误,知道为什么会这样发生了什么?
问题是您的宏陷入了错误的模式。你认为应该应用这个:
[(>> f1 f2 rf ...)
(>> (lambda (x) (f2 (f1 x))) rf ...)]))
但实际上它实际上可以匹配这个模式:
[(>> f1 [args ...])
(lambda (x) (f1 args ... x))]
与 f1
匹配 (lambda (x) (+ x 1))
,(args ...)
匹配 (lambda (x) x)
。扩展为:
(lambda (x) ((lambda (x) (+ x 1)) lambda (x) x x))
这是胡言乱语。您可能最好使用需要在每个参数周围加上括号的模式:
(define-syntax >> ;;compose
(syntax-rules ()
[(>> (f1 args ...))
(lambda (x) (f1 args ... x))]
[(>> (f1 args1 ...) (f2 args2 ...) rf ...)
(>> (lambda (x) (f2 args2 ... (f1 args1 ... x)) ) rf ... )]))
这也减少了您需要的参数数量。要使用它,请执行:
(define composed-function (>> ((lambda (x) (+ x 1))) ((lambda (x) (+ x 1)))))
当然,第三种选择就是使用racket/base
中的compose
。不可否认,它不允许您为每个函数传递固定参数,但您仍然可以通过 eta-expansion 获得它。
要使用 compose
,您的示例将如下所示:
(define composed-function (compose (lambda (x) (+ x 1)) (lambda (x) (+ x 1))))
(请注意,尽管函数与您的示例相反。)