我被告知以下表达式旨在评估为0,但Scheme的许多实现将其评估为1:
(let ((cont #f))
(letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0)))
(y (call-with-current-continuation (lambda (c) (set! cont c) 0))))
(if cont
(let ((c cont))
(set! cont #f)
(set! x 1)
(set! y 1)
(c 0))
(+ x y))))
Run Code Online (Sandbox Code Playgroud)
我必须承认,我不知道从哪里开始.我理解延续的基础知识call/cc
,但是我可以得到这个表达式的详细解释吗?
双方letrec
并letrec*
在R6RS,但有只 letrec
球拍,没有letrec*
.这些有什么区别?
可以使用let rec创建无限的循环列表,而无需求助于可变引用:
let rec xs = 1 :: 0 :: xs ;;
Run Code Online (Sandbox Code Playgroud)
但是我可以使用相同的技术来编写一个接收有限列表并返回其无限循环版本的函数吗?我尝试写作
let rec cycle xs =
let rec result = go xs and
go = function
| [] -> result
| (y::ys) -> y :: go ys in
result
;;
Run Code Online (Sandbox Code Playgroud)
但是出现了以下错误
错误:不允许这种表达式作为`let rec'的右侧
我想了解let
绑定在Haskell中是如何工作的(或者如果Haskell实现不同,可能是lambda演算?)
我从阅读中理解为你写了一个Haskell,它对单个let
绑定有效.
let x = y in e == (\x -> e) y
Run Code Online (Sandbox Code Playgroud)
这对我来说很有意义,因为它与lambda演算中绑定的工作方式一致.我很困惑的地方是使用多个let
绑定,其中一个绑定可以引用上面的绑定.我将提供一个简单的例子.
原始代码:
let times x y = x * y
square x = times x x
in square 5
Run Code Online (Sandbox Code Playgroud)
我对实施的猜测:
(\square times -> square 5) (\x -> times x x) (\x -> x * x)
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用,因为times
当lambda调用square时没有定义.但是,这可以通过此实现解决:
(\square -> square 5) ((\times x -> times x x) (\x -> x * x))
Run Code Online (Sandbox Code Playgroud)
这是实现此绑定的正确方法,至少在lambda演算中是这样吗?
我不明白它们之间的区别(对于人为的例子而言):
(define average
(lambda (elems)
(define length
(lambda (xs)
(if (null? xs)
0
(+ 1 (length (cdr xs))))))
(define sum
(lambda (xs)
(if (null? xs)
0
(+ (car xs) (sum (cdr xs))))))
(define total (sum elems))
(define count (length elems))
(/ total count)))
Run Code Online (Sandbox Code Playgroud)
和
(define average
(lambda (elems)
(letrec ((length
(lambda (xs)
(if (null? xs)
0
(+ 1 (length (cdr xs))))))
(sum
(lambda (xs)
(if (null? xs)
0
(+ (car xs) (sum (cdr xs))))))
(total (sum elems))
(count (length elems))) …
Run Code Online (Sandbox Code Playgroud) 我正在努力区分 let、letrec、let* 之间的区别......因为scheme不是我的主要编程语言,我的记忆已经存在很长时间了..我有这个功能..现在我在这里对letrec感到非常困惑..这又是递归。我可以理解……但在这段代码中无法建立足够的连接……(可能仍然对递归感到困惑)有人可以解释为什么这里需要 letrec
(define myFunc
(lambda (start end res func)
(letrec ((func:rec_func
(lambda (x i y)
(if (>= i start)
(func:rec_func (cons i x) (- i res) (cons (func i) y)) ;; line6
(cons x (cons y '())))))) ;; line7
(func:rec_func '() end '()))))
Run Code Online (Sandbox Code Playgroud)
(已编辑)我所理解的尾递归
-> [Q1] 它是尾递归吗?
-> [Q2] 那么,是否应该始终使用 letrec 进行尾递归?
此函数返回 x、y 的列表,边界为 start、end,因此它检查索引 i 是否在边界内,如果是,则执行第 6 行
-> [Q3]那么,第 6 行是什么?我无法得到 line6