Racket 球拍是否允许功能过载?

Racket 球拍是否允许功能过载?,racket,Racket,我不熟悉Lisp scheme,也不熟悉整个函数范式,目前正在做一项作业,要求我在racket中重载一个名称相同但参数集不同的函数。下面是我努力实现的一个例子: #lang racket (define (put-ball-in-box two-by-fours nails ball) ... ) (define (put-ball-in-box box ball) ... ) 这些不是实际的功能,但已经足够接近了。正如所暗示的那样,这两个函数都会将一个球放入一个盒子中,但其中一个

我不熟悉Lisp scheme,也不熟悉整个函数范式,目前正在做一项作业,要求我在
racket
中重载一个名称相同但参数集不同的函数。下面是我努力实现的一个例子:

#lang racket

(define (put-ball-in-box two-by-fours nails ball)
  ... )

(define (put-ball-in-box box ball)
  ... )
这些不是实际的功能,但已经足够接近了。正如所暗示的那样,这两个函数都会将一个球放入一个盒子中,但其中一个函数会首先从盒子的组件组装盒子,然后调用另一个。显然,当我在DrRacket中尝试上述操作或使用命令行时,会得到一个
模块:标识符的重复定义…
错误

有没有办法在球拍中实现这一点

也许答案就在我面前,但我已经花了两个小时寻找这个,什么也找不到,所以如果有任何指点,我将不胜感激


谢谢。

这不是通常意义上的“在其他地方写另一个定义”

它允许阴影,即定义与导入过程同名的过程。因此,您可以
(定义+…)
,而
+
的定义将
+
隐藏在
球拍/球座
中。如果需要原始过程,那么可以执行如下操作,其中我将
+
定义为加法或字符串追加

 #lang racket/base
 (require (rename-in racket/base (+ base:+)))

 (define (+ . args)
   (if (andmap string? args)
       (apply string-append args)
       (apply base:+ args)))
另一件事是使用
racket/match
,根据参数的形状有不同的行为

#lang racket/base
(require racket/match)
(define (fib . arg)
  (match arg
   [(list n) (fib n 1 0)]
   [(list 1 a b) a]
   [(list 0 a b) b]
   [(list n a b) (fib (sub1 n) (+ a b) a)]))
第二个示例仍然没有达到您想要的效果,因为您必须转到原始定义点并修改
match
子句。但这对于你的目的来说可能已经足够了


一个更复杂的例子是使用自定义语法创建
define/重载
表单。但是我认为您会发现
球拍/比赛
解决方案是最好的。

您有JS和PHP中默认值的概念:

(define (fib n (a 0) (b 1))
  (if (zero? n)
      a
      (fib (sub1 n) b (+ a b))))

(fib 10) ; ==> 55
现在,如果您有5个可选参数,您需要对它们进行排序,甚至传递一些值,以便能够添加后面的参数。为了避免这种情况,您可以使用关键字:

(define (test name #:nick [nick name] #:job [job "vacant"])
  (list name nick job))

(test "sylwester" #:job "programmer")
; ==> ("sylwester" "sylwester" "programmer")
现在球拍有课了。您可以调用类似
(发送对象方法args…)
的方法


请注意,这两个类并没有真正提交到带有
area
的联合接口,因此这是纯duck类型。因此,您可以创建一个函数,该函数需要一个实现消息的类,而不必担心该类的其他方面。

谢谢您的回答。我测试了你的和《生命法则》中的一个,两个都会起作用,所以既然我不能同时接受这两个,那么我就要给你的投票,因为它也很有帮助,并且接受《生命法则》中的一个给后代。@Claudiusbr出于好奇,我添加了OO。虽然我通常会像你一样写出来,FWIW还有一些小方糖,如
define/match
match lambda
match lambda*
,等等。请注意,还有一些方糖可以编译得更高效,但与
match
相比,通用性较差。您可以制作自己版本的
define
,以实现这类功能。但这不是一个初学者的项目。以Formica为例:
(define circle%
  (class object%
    (super-new)
    (init-field radius)
    (define/public (area)
      (* radius radius 3.1415))))

(define cube%
  (class object%
    (super-new)
    (init-field side)
    (define/public (area)
      (* side side))))


(define circle (new circle% [radius 7]))
(define cube (new cube% [side 7]))

(map
 (lambda (o) (send o area))
 (list circle cube))
; ==> (153.9335 49)