我正在嘗試僅使用基本功能(car、cdr、cons 等)比較 Scheme 中串列串列中的條目,但不知道如何迭代串列。我試著寫這個:
(define (iterate L X)
(cond ((null? L) '())
((> X 0) (iterate ((cdr L) (- X 1))))
))
但我不確定為什么它不起作用。我的想法是 iterate 只會回傳 n cdr 之后的串列串列。所以例如我試圖得到:
(iterate ( ((10 20) (20 30) (30 40) (40 50)) '2)) -> ((30 40) (40 50))
(iterate ( ((10 20) (20 30) (30 40) (40 50)) '3)) -> ((40 50))
這是我得到的錯誤,不知道是什么意思:
*** ERROR: invalid application: (20 30)
Stack Trace:
_______________________________________
0 (20 30)
At line 45 of "./main.sc"
1 ((10 20) (20 30) (30 40) (40 50))
At line 45 of "./main.sc"
2 (((10 20) (20 30) (30 40) (40 50)) '3)
At line 45 of "./main.sc"
3 (iterate (((10 20) (20 30) (30 40) (40 50)) '3))
At line 45 of "./main.sc"
任何幫助表示贊賞。謝謝!
uj5u.com熱心網友回復:
有兩個基本問題:
- 在 Scheme 中,不要用括號將函式引數括起來;語法是
(function arg1 arg2),不是(function (arg1 arg2))。后者首先將程序arg1應用于arg2,然后將其結果傳遞給function。 ((10 20) (20 30) (30 40) (40 50))不創建串列,它嘗試將程序(10 20)應用于引數(20 30),(30 40)和(40 50)。您的實作評估第一個引數 –(20 30)– first, before(10 20),并嘗試將其20作為程序應用于引數30。這是“無效的申請”。
(如果首先評估了該程式,您會看到“無效的申請:(10 20)”。)
您需要參考您的串列引數或使用該list程序。
解決這兩個問題給出
(define (iterate L X)
(cond ((null? L) '())
((> X 0) (iterate (cdr L) (- X 1)))))
和
(iterate '((10 20) (20 30) (30 40) (40 50)) '3)
現在您只需要解決X在串列為空之前達到零時出現的問題...
uj5u.com熱心網友回復:
基本上Scheme中的所有控制流,甚至是報告中的控制流,都是遞回程序的語法糖。例如。當你用 JS 寫這個時:
const arr = [];
for (let e of lst) {
arr.push(e*2);
}
return arr;
在 Scheme 中,你會這樣寫:
(define (loop lst acc)
(if (null? lst)
(reverse acc)
(loop (cdr lst) (cons (* (car lst) 2) acc))))
(loop lst '())
我們甚至有一個語法糖可以更清楚地做到這一點:
(let loop ((lst lst) (acc '()))
(if (null? lst)
(reverse acc)
(loop (cdr lst) (cons (* (car lst) 2) acc))))
在 JS 中,我們有Array.forEach,Array.reduce和Array.map. 在流程,我們有for-each,fold-left,fold-right,和map。例如。上面的代碼在JS中可以這樣寫:
[1, 2, 3, 4].map(v => v*2); // ==> [2, 3, 6, 8]
像這樣在Scheme中:
(map (lambda (v) (* v 2)) lst) ; ==> (2 3 6 8)
所以我猜你不能使用這些串列程序,但是你可以自己創建它或者像我的第一個例子一樣滾動你自己的遞回。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/328819.html
上一篇:異步發布父子物件和關系(遞回?)
