2016-05-16 29 views
1

我發現了一個簡短的介紹方案的在線和我有一點麻煩使用此項功能:在函數定義中調用非過程?

(define (title-style str) 
    (let loop ((lC#\space) (i 0) (c (string-ref str 0))) 
    ((if (char=? lC#\space) 
     (string-set! str i (char-upcase c))) 
    (if (= (- (string-length str) 1) i) 
     str 
     (loop c (+ i 1) (string-ref str (+ i 1))))))) 

(display "star wars iv: a new hope") 
(display (title-style "star wars iv: a new hope")) 

當我嘗試調用它,我得到這個:

Error: call of non-procedure: #<unspecified> 

    Call history: 

    title-style.scm:6: loop 
    ... 
    title-style.scm:1: g6   <-- 

該錯誤來自Chicken計劃,我也在Chez計劃中獲得了同樣的結果。

它一個字符串轉換爲標題情況,並從我剛纔得到了錯誤的信息,它的作用:call of non-procedure: "Star Wars Iv: A New Hope"

回答

3

我明白你打算做什麼,但是這並不是結構方案的條件表達式的正確方法。另外,在第一個if之前,有一個錯位的開括號(這是導致報告的錯誤的那個),並且必須在所有情況下提前遞歸。這應該非空字符串工作:

(define (title-style str) 
    (let loop ((lC#\space) (i 0) (c (string-ref str 0))) 
    (cond ((= (- (string-length str) 1) i) 
      str) 
      ((char=? lC#\space) 
      (string-set! str i (char-upcase c)) 
      (loop c (+ i 1) (string-ref str (+ i 1)))) 
      (else 
      (loop c (+ i 1) (string-ref str (+ i 1))))))) 

但儘管如此,它,你變異一路走來,不建議使用這種輸入字符串不是寫在計劃解決方案的推薦方式,而你在索引方面思考。此外,您對輸入施加了額外的限制:字符串必須是可變的,並且並非所有Scheme方言默認支持

函數尾遞歸風格是首選,我們創建一個新的字符串作爲輸出,保持原始輸入不變,並利用語言中可用的豐富的列表過程庫;這就是我的意思是:

(define (title-style str) 
    (let loop ((lC#\space) (lst (string->list str)) (acc '())) 
    (cond ((null? lst) 
      (list->string (reverse acc))) 
      ((char=? lC#\space) 
      (loop (car lst) (cdr lst) (cons (char-upcase (car lst)) acc))) 
      (else 
      (loop (car lst) (cdr lst) (cons (car lst) acc)))))) 

無論哪種方式,它按預期工作:

(title-style "star wars iv: a new hope") 
=> "Star Wars Iv: A New Hope" 
+1

另外一個使用'與字符串> list'和'列表 - > string'辦法上攻(相比於'string-ref'是在R7RS上,'string-ref'(和'string-set!')允許爲O(n)(對於字符串在內部表示爲UTF-8的實現,所以每個字符可以佔用不同數量的字節)。 –

+0

感謝您的幫助。我仍然試圖圍繞細胞如何工作,這是很大的幫助。 – user1610406

+0

當參數的計算結果爲字符串常量時,默認情況下沒有實現支持這種方式。雞,球拍,Gambit,Ikarus都顯示未定義的行爲,並且通常不會像報告中推薦的那樣發出錯誤信號。 – Sylwester

相關問題