gpt4 book ai didi

numbers - 创建后缀号码 Racket

转载 作者:行者123 更新时间:2023-12-02 17:06:01 27 4
gpt4 key购买 nike

我正在尝试在 Racket 中尝试做什么,并且我想在数字后加上字母。

对于此示例,我只想将 10000 表示为 10K,将 1000000 表示为 1M .

有没有办法(使用宏或其他方式)将 1M 扩展为:

(* 1 1000000)

或者有类似效果的东西吗?

最佳答案

在 Racket 中,像 10K 这样的东西是标识符,通常指的是变量。有两种方法可以将它们变成数字:

1:重新定义“未定义”标识符的含义

您可以通过定义 #%top 宏来重新定义对未定义标识符执行的操作。

#lang racket
(require syntax/parse/define
(only-in racket [#%top old-#%top]))

(define-syntax-parser #%top
[(_ . x:id)
#:when (id-has-a-k-at-the-end? #'x)
(transform-id-into-number #'x)]
[(_ . x)
#'(old-#%top . x)])

但是,这有一个微妙的问题。如果程序中存在任何以 K 结尾的标识符或变量,它们可能会覆盖以这种方式编写的任何数字。您需要小心,不要意外覆盖原本应该是数字的内容。

2:制作一个阅读器扩展,将它们转换为数字而不是标识符

这会花费更多时间,但它更接近“正确的方法”,因为它可以避免当变量末尾恰好有 K 时发生冲突。

扩展阅读器的更简单方法之一是使用 readtable 。您可以创建一个扩展可读表的函数,如下所示:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
;; Char InputPort Any Nat Nat Nat -> Any
(define (rt-proc char in src ln col pos)
....)
...
(make-readtable orig-rt
#f 'non-terminating-macro rt-proc
...))

要使用它来定义#lang语言,您需要将阅读器实现放在your-language/lang/reader.rkt中。这里是 number-with-k/lang/reader.rkt,其中 number-with-k 目录作为单个集合包 (raco pkg安装 path/to/number-with-k)。

number-with-k/lang/reader.rkt

#lang racket

(provide (rename-out [-read read]
[-read-syntax read-syntax]
[-get-info get-info]))

(require syntax/readerr
syntax/module-reader)

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
;; Char InputPort Any Nat Nat Nat -> Any
(define (rt-proc char in src ln col pos)
....)
...
(make-readtable orig-rt
#f 'non-terminating-macro rt-proc))

;; [X ... -> Y] -> [X ... -> Y]
(define ((wrap-reader rd) . args)
(parameterize ([current-readtable (extend-readtable (current-readtable))])
(apply rd args)))

(define-values [-read -read-syntax -get-info]
(make-meta-reader 'number-with-k
"language path"
lang-reader-module-paths
wrap-reader
wrap-reader
identity))

主要工作是填补 extend-readtable 函数中的 .... 漏洞。例如,您可以让它识别以 K 结尾的标识符,如下所示:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
;; Char InputPort Any Nat Nat Nat -> Any
(define (rt-proc char in src ln col pos)
(define v (read-syntax/recursive src in char orig-rt #f))
(cond
[(and (identifier? v) (id-has-a-k-at-the-end? v))
(transform-id-into-number v)]
[else
v]))

(make-readtable orig-rt
#f 'non-terminating-macro rt-proc))

完成此操作后,并且您已将 number-with-k 目录作为软件包安装,您应该能够使用 #lang number-with-k像这样:

#lang number-with-k racket

(+ 12K 15)
; => 12015

关于numbers - 创建后缀号码 Racket ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53544083/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com