2016-05-16 10 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   <-- 

というエラーが私はChez Schemeで同じ結果を得ています。

それがタイトルケースに文字列を変換し、私が以前持っエラーメッセージから、それがない: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

Anがに比べて 'はstring-> list'と'リスト - > STRING'のアプローチを(使用しての逆を追加しました'string-ref')はR7RS上で、' string-ref'(そして 'string-set!')はO(n)であることが許されています(文字列がUTF-異なるバイト数を占めることがあります)。 –

+0

助けてくれてありがとう。私はまだコンスセルがどのように動作するかについて頭を落とそうとしていますが、これは大いに役立っています。 – user1610406

+0

おそらく実装が、引数が文字列定数に評価されるとき、これはデフォルトでサポートされません。 Chicken、Racket、Gambit、Ikarusはすべて定義されていない動作を表示します。 – Sylwester

関連する問題