在函数定义中调用非过程?
Call of non-procedure in function definition?
在网上找了一个Scheme的简单介绍,这个功能我遇到了点麻烦:
(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 Scheme,我在 Chez Scheme 中也得到了相同的结果。
它将字符串转换为首字母大写,从我之前收到的错误消息来看,它确实是:call of non-procedure: "Star Wars Iv: A New Hope"
我明白你打算做什么,但这不是在 Scheme 中构建条件表达式的正确方法。此外,就在第一个 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 中编写解决方案的推荐方法,您正在沿途改变输入字符串,这是不鼓励的,并且您正在考虑索引。此外,您对输入施加了额外的限制:字符串必须是可变的,并且并非所有 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"
在网上找了一个Scheme的简单介绍,这个功能我遇到了点麻烦:
(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 Scheme,我在 Chez Scheme 中也得到了相同的结果。
它将字符串转换为首字母大写,从我之前收到的错误消息来看,它确实是:call of non-procedure: "Star Wars Iv: A New Hope"
我明白你打算做什么,但这不是在 Scheme 中构建条件表达式的正确方法。此外,就在第一个 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 中编写解决方案的推荐方法,您正在沿途改变输入字符串,这是不鼓励的,并且您正在考虑索引。此外,您对输入施加了额外的限制:字符串必须是可变的,并且并非所有 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"