给定一个表达式'(lambda(x)x)如何将其转换为字符串。我认为symbol-> string会完成这项工作,但不能没有符号。
例如对于一个宏的字符串:( to-string(lambda(x)x))这应该返回>>“(lambda(x)x)”
任何想法的人都谢谢
标准方案(至少在R5RS意义上)无法做到这一点,所以如果你想要可移植的代码,你需要自己走这个结构。繁琐但不太复杂(即使是虚线列表)。但是如果你只是想要一些工作版本,那么你应该查看你的实现手册并搜索这样做的方法。答案几乎总是很简单,例如,在PLT Scheme中你会使用(format "~s" '(lambda ...))
表达式'(lambda (x) x)
是一个引用列表。
表达式(lambda (x) x)
是运行时的某种编译,不透明,可执行的内部对象。
symbol->string
只是将符号转换为字符串,这是一个字符序列。
如果您正在使用列表,则可以简单地遍历列表并打印出各个组件。实际上,(write '(lambda (x) x))
只会打印清单。
许多方案都有类似于(with-output-to-string ... )
的东西,它返回写入标准端口的所有输出的字符串。
但是,如果你做(write (lambda (x) x))
,你会得到谁知道什么。转储可执行函数类型时,您将获得实现提供的任何内容。有些人可能会打印一个显示源代码的“反汇编”。其他人可能只是打印#function
或同样无用的东西。
简而言之,如果您只想打印一个列表,那么有各种各样的机制。
如果你想打印出编译函数的源代码,这是一个完全不同的问题,非常依赖于实现,而且可能是不可能的。
(pretty-format v [columns]) → string?
你应该走过一些洞穴。当一个新的缺点开始写“(”,当它结束写“)”“并使用符号 - >字符串表示在conses内的符号。
您可以使用类型调度来扩展它。方案中也可能存在漂亮的印刷品吗?
这是一个简单的代码,我认为,它可以满足您的需求。 它没有使用特定于实现的东西,而且非常简单。
但请注意,它不能正确处理字符串中的特殊字符(例如“a”,“b”,“c”将变为“a”b“c”)。
(define join
(lambda (l delim to-str)
(fold-left
(lambda (str elem)
(string-append str delim (to-str elem)))
(to-str (car l))
(cdr l))))
(define sexpr->string
(lambda (sexpr)
(cond
((number? sexpr) (number->string sexpr))
((symbol? sexpr) (symbol->string sexpr))
((boolean? sexpr) (if sexpr "#t" "#f"))
((string? sexpr) (string-append "\"" sexpr "\""))
((char? sexpr) (string-append "#\\" (string sexpr)))
((vector? sexpr)
(let ((s-vec (join (vector->list sexpr) " " sexpr->string)))
(string-append "#(" s-vec ")")))
((null? sexpr) "()")
((list? sexpr) (string-append "(" (join sexpr " " sexpr->string) ")"))
((pair? sexpr)
(let ((s-car (sexpr->string (car sexpr)))
(s-cdr (sexpr->string (cdr sexpr))))
(string-append "(" s-car " . " s-cdr ")"))))))
如果您使用的是R6RS兼容方案,则可以将write
函数与call-with-string-output-port
结合使用。
#!r6rs
(import (rnrs base)
(rnrs io ports) ;for call-with-string-output-port
(rnrs io simple)) ;for write
;; Produces a string representation of the S-Expression e
(define (expr->string e)
(call-with-string-output-port
(lambda (out) (write e out))))
一些例子:
> (expr->string '(lambda (x) (+ x 1)))
"(lambda (x) (+ x 1))"
> (expr->string '(lambda (x) (string-append x " and cheese!")))
"(lambda (x) (string-append x \" and cheese!\"))"
顺便说一下,使用read
和open-string-input-port
,通常也可以向另一个方向前进。
;; Produces the S-Expression represented by the string.
;; In most cases this will be a left-inverse of expr->string,
;; so that (string->expr (expr->string e)) = e.
;; If the string has multiple S-Expressions represented
;; in it, this only returns the first one.
(define (string->expr s)
(read (open-string-input-port s)))
一些例子:
> (string->expr "(lambda (x) (+ x 1))")
(lambda (x) (+ x 1))
> (equal? (string->expr "(lambda (x) (+ x 1))")
'(lambda (x) (+ x 1)))
#t
> (equal? (string->expr (expr->string '(lambda (x) (+ x 1))))
'(lambda (x) (+ x 1)))
#t