Io 如何从输入文件中引用列表
有很多关于如何在scheme中输入的手册,但我不知道如何使用它。 假设我们有一个简单的txt文件作为输入 a、 txt: 1 2 3 我正在调用它的标准io过程Io 如何从输入文件中引用列表,io,scheme,racket,Io,Scheme,Racket,有很多关于如何在scheme中输入的手册,但我不知道如何使用它。 假设我们有一个简单的txt文件作为输入 a、 txt: 1 2 3 我正在调用它的标准io过程 (let ((p (open-input-file "a.txt"))) (let f ((x (read p))) ; reading from file (if (eof-object? x) ; check for eof (begin (close-input-port p) '()
(let ((p (open-input-file "a.txt")))
(let f ((x (read p))) ; reading from file
(if (eof-object? x) ; check for eof
(begin
(close-input-port p)
'()
)
(cons x (f (read p))))))
输出:
"(1 2 3)
这是我正在寻找的东西,但如果我想对其进行标准的配对/列表操作,我没有得到我所期望的:
(let ((p (open-input-file "a.txt")))
(let f ((x (read p))) ; reading from file
(if (eof-object? x) ; check for eof
(begin
(close-input-port p)
'()
)
(cdr
(cons x (f (read p)))))))
输出:
“()
如何获取列表的其余部分?请注意,要操作的列表是由
(let…
表达式构建的,即:
(let ((p ...)) ...) ;; => '(1 2 3)
(cdr (let ((p ...)) ...)) ;; => '(2 3)
因此,要获得列表的“其余部分”,必须对整个let表达式应用cdr
,即:
(let ((p ...)) ...) ;; => '(1 2 3)
(cdr (let ((p ...)) ...)) ;; => '(2 3)
在let表达式外部应用cdr
与在内部应用不同。当您在外部应用它时,let表达式首先被计算为一个列表,该列表cdr
然后进行操作以获取其“rest”值。这相当于写:
(cdr '(1 2 3)) ;; => '(2 3)
但是如果你在它的主体中应用它,那么在每次递归调用f
时,其中一个cons
单元格被递归地追加到列表中,你最终会将一个cdr
链接到它,而不是像下面那样构建一个cons链:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
而是构建一个表单链:
(cdr (cons 1 (cdr (cons 2 (cdr (cons 3 '())))))) ;; => '()
要了解这是如何发生的,最好从思想上考虑或写下程序的执行流程。这使您能够理解表达式的计算结果 例如,可以将第一个let表达式重写为等效函数,如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
它的执行流程如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
但是如果您将cdr
应用于递归调用,如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
然后执行将更改为以下内容:
(f (read p))
=> (f 1)
=> (cdr (cons 1 (f (read p))))
=> (cdr (cons 1 (f 2)))
=> (cdr (cons 1 (cdr (cons 2 (f (read p))))))
=> (cdr (cons 1 (cdr (cons 2 (f 3)))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 (f (read p))))))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 (f eof)))))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 '()))))))
=> (cdr (cons 1 (cdr (cons 2 '()))))
=> (cdr (cons 1 '()))
=> '()
请注意,要操作的列表是由
(let…
表达式构造的,即:
(let ((p ...)) ...) ;; => '(1 2 3)
(cdr (let ((p ...)) ...)) ;; => '(2 3)
因此,要获得列表的“其余部分”,必须对整个let表达式应用cdr
,即:
(let ((p ...)) ...) ;; => '(1 2 3)
(cdr (let ((p ...)) ...)) ;; => '(2 3)
在let表达式外部应用cdr
与在内部应用不同。当您在外部应用它时,let表达式首先被计算为一个列表,该列表cdr
然后进行操作以获取其“rest”值。这相当于写:
(cdr '(1 2 3)) ;; => '(2 3)
但是如果你在它的主体中应用它,那么在每次递归调用f
时,其中一个cons
单元格被递归地追加到列表中,你最终会将一个cdr
链接到它,而不是像下面那样构建一个cons链:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
而是构建一个表单链:
(cdr (cons 1 (cdr (cons 2 (cdr (cons 3 '())))))) ;; => '()
要了解这是如何发生的,最好从思想上考虑或写下程序的执行流程。这使您能够理解表达式的计算结果 例如,可以将第一个let表达式重写为等效函数,如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
它的执行流程如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
但是如果您将cdr
应用于递归调用,如下所示:
(cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define p (open-input-file "a.txt"))
;; (let f (...) ...) is a named let,
;; and is equivalent to the function below.
(define (f x)
(if (eof-object? x)
'()
(cons x (f (read p)))))
(f (read p))
(close-input-port p)
(f (read p))
=> (f 1)
=> (cons 1 (f (read p)))
=> (cons 1 (f 2))
=> (cons 1 (cons 2 (f (read p))))
=> (cons 1 (cons 2 (f 3)))
=> (cons 1 (cons 2 (cons 3 (f (read p)))))
=> (cons 1 (cons 2 (cons 3 (f eof))))
=> (cons 1 (cons 2 (cons 3 '()))) ;; => '(1 2 3)
(define (f x)
(if (eof-object? x)
'()
(cdr (cons x (f (read p))))))
然后执行将更改为以下内容:
(f (read p))
=> (f 1)
=> (cdr (cons 1 (f (read p))))
=> (cdr (cons 1 (f 2)))
=> (cdr (cons 1 (cdr (cons 2 (f (read p))))))
=> (cdr (cons 1 (cdr (cons 2 (f 3)))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 (f (read p))))))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 (f eof)))))))
=> (cdr (cons 1 (cdr (cons 2 (cdr (cons 3 '()))))))
=> (cdr (cons 1 (cdr (cons 2 '()))))
=> (cdr (cons 1 '()))
=> '()
太多了!我需要它就行了。只是一个简单的问题。为什么我不能在let中以同样的方式进行cdr?无论如何,我都会将其分配给p。@Adam查看我上面的编辑,以了解为什么在计算列表的表达式之外应用
cdr
与在其主体内应用cdr
不同。谢谢!我需要它就行了。只是一个简单的问题。为什么我不能在let中以同样的方式进行cdr?无论如何,我都会将其分配给p。@Adam请参阅我上面的编辑,以了解为什么在对列表求值的表达式外部应用cdr
与在其主体中应用cdr
不同。