给定一个表达式 '(lambda (x) x),我该如何将其转换为字符串。我认为symbol->string可以完成这个任务,但它不能转换符号。
例如,对于一个名为to-string的宏:
(to-string (lambda(x) x)),这应该返回 >> "(lambda (x) x)"
有什么想法吗?谢谢。
给定一个表达式 '(lambda (x) x),我该如何将其转换为字符串。我认为symbol->string可以完成这个任务,但它不能转换符号。
例如,对于一个名为to-string的宏:
(to-string (lambda(x) x)),这应该返回 >> "(lambda (x) x)"
有什么想法吗?谢谢。
标准方案(至少在R5RS意义上)无法做到这一点,因此如果您希望代码具有可移植性,则需要自己遍历结构。 繁琐但不太复杂(即使对于带点列表也是如此)。
但是,如果您只想要一些工作版本,那么您应该查看实现手册并搜索如何执行此操作的方法。 答案通常很简单,例如,在PLT Scheme中,您将使用(format "~s" '(lambda ...))
write
操作。 - C. K. Youngformat
。(是的,参考实现使用srfi-6,但实现通常会使用任何内置功能——mzscheme实现srfi-26只使用了自己的“format”。) - Eli Barzilay'(lambda (x) x)
这个表达式是一个带引号的列表。
(lambda (x) x)
这个表达式是一种编译后的不透明可执行内部对象。
symbol->string
函数只是将一个符号转换为一个字符串,而这个字符串是由一系列字符组成的。
如果你正在处理一个列表,那么你可以简单地遍历该列表并打印出各个组件。实际上,(write '(lambda (x) x))
只会简单地打印该列表。
许多Scheme方言都有类似于(with-output-to-string ... )
的机制,用于返回所有写入标准端口的输出字符串。
然而,如果你执行(write (lambda (x) x))
,你将得到谁知道什么样的结果。你会得到实现在转储可执行函数类型时所提供的任何内容。有些可能会打印出显示源代码的"反汇编"。其他人则可能只是打印出#function
或类似无用的东西。
总之,如果你只想打印一个列表,那么有各种机制可以做到这一点。
如果你想打印已编译函数的源代码,则需要解决完全不同的问题,这与具体实现有关,可能是不可能的。
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
}}与{{link2: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
(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 ")"))))))