【问题标题】:Scheme: Changing the definition of complex numbers to accept vectors方案:更改复数的定义以接受向量
【发布时间】:2014-03-19 03:35:07
【问题描述】:

基本上我想做的是改变复数的定义,这样我就可以在 Scheme 中表示向量。我希望能够在没有引号的情况下编写类似“i+j+k”的内容,并且不会让程序完全发疯。我知道复数可以用“1+2i”之类的东西来表示,所以我希望一个简单的覆盖就可以实现这一点。

我想覆盖复杂的?定义可能有效,但似乎没有效果。我不确定我需要影响的代码在哪里。任何帮助都会很棒。谢谢。

【问题讨论】:

  • 为什么要专门写成“i + j + k”而不是有序列表表示法(i,j,k)?

标签: vector scheme racket definition overwrite


【解决方案1】:

Scheme 标准中当然没有提供修改 Scheme 阅读器,因此需要您为您选择的 Scheme 实现更改“阅读器”——这是一项不平凡的任务。

最好使用 Scheme 的宏和抽象工具将自己的语言嵌入到 Scheme 中。

假设您有 i、j 和 k 的坐标基础,并且您希望将向量表示为例如 2i+​​7j-k。你可以从:

(define (make-coord i j k) (vector i j k))
(define (coord-i b) (vector-ref b 0))
…

那么如果你想让事情更容易表达:

(define-syntax coord
  (syntax-rules ()
    ((coord i j k) (make-coord i j k))))

您将用作:

(define a-coord (coord 2 7 -1))

编辑:这是一个例子。我用list替换了make-coord

> (define-syntax coord
    (syntax-rules ()
      ((coord i j k) (list i j k))))
> (coord 1 1 1)
(1 1 1)

请注意,使用语法/函数而不是阅读器的优点之一是您可以使用表达式:

> (coord (/ 124 4) 0 0)
(31 0 0)

【讨论】:

  • 在我的回答中,您无需致电make-coord - 您只需致电vectorlist。我使用make-coord 是因为我认为您可能想要封装您的数据并定义一些访问器,例如coord-i 等。
【解决方案2】:

简而言之:你不能用“简单的覆盖”来完成你想要的。 数字的语法包括用于读取/写入复数的 +,但 阅读器将 2+3i 直接转换为数字,没有任何覆盖选项。

如果您想在程序中使用中缀表示法,您需要更换阅读器。这在 Racket 中是可能的,但它比简单的覆盖更复杂。

也许您可以在 Racket 中使用现有的库来表示中缀符号?

您可能想尝试一下:

https://github.com/soegaard/this-and-that/blob/master/readtable/test2.rkt

将 {} 中的任何内容解析为中缀表达式。

【讨论】:

    【解决方案3】:

    您是否知道 Racket 阅读器已经支持复杂的文字数字?

    来自the Reference的示例:

    1+2i 等于 (make-complex 1 2)

    1/2+3/4i 等于 (make-complex (/ 1 2) (/ 3 4))

    1.0+3.0e7i 等于 (exact->inexact (make-complex 1 30000000))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2012-06-14
      相关资源
      最近更新 更多