球拍是否允许功能超载?

问题描述 投票:3回答:2

我是Lisp-scheme的新手,对整个函数范例都是新手,我目前正在做一个赋值,要求我重载一个具有相同名称但在racket中不同参数集的函数。下面是我想要实现的一个例子:

#lang racket

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

(define (put-ball-in-box box ball)
  ... )

这些不是实际功能,但足够接近。正如所暗示的那样,两个函数都会将一个球放在一个盒子里,但是一个人会首先从其组件中组装盒子,然后调用另一个盒子。显然,当我在DrRacket中尝试上述操作或使用命令行时,我得到一个module: duplicate definition for identifier ...错误。

有没有办法在racket实现这一目标?

也许答案就在我面前,但我花了最后两个小时搜索这个并找不到任何东西,所以我会很感激任何指针。

谢谢。

racket
2个回答
3
投票

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

它允许阴影,它定义一个与导入过程同名的过程。因此你可以(define + ...)和你对+的定义将隐藏+racket/base。如果你想要原始程序,那么你可以做类似下面的事情,我将+定义为加法或字符串附加。

 #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/overload表单。但我认为你会发现racket/match解决方案是最好的。


3
投票

你有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")

现在,Racket有课程。你可以调用像(send object method args ...)这样的方法。

(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)

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

© www.soinside.com 2019 - 2024. All rights reserved.