我正在DrRacket上调试此代码:
MemoryStore
代码#lang racket
(define last-element-on-list
(lambda l
(cond ((null? l) '())
((null? (cdr l)) (car l))
(else (last-element-on-list (cdr l)))
)
)
)
(define lst '(
(n 25 f +)
(s 25 m +)
(ll 20 no -)))
(list-ref lst 0)
(last-element-on-list (list-ref lst 0))
返回(list-ref lst 0)
,但是当我进入过程'(n 25 f +)
时,参数last-element-on-list
的值为l
。
为什么((n 25 f +))
是过程l
中的列表列表?
答案 0 :(得分:4)
using System;
namespace OverloadResolution
{
class Program
{
static void Main(string[] args)
{
string[] foo = new string[] { "A", "B", "C" };
Extensions.PrintMe2(foo); // <<< Note the PrintMe2 function
Extensions.PrintMe2("Hello world"); // <<< Note the PrintMe2 function
Console.ReadLine();
}
}
public static class Extensions
{
public static void PrintMe2<T>(T elm)
{
PrintMe(elm);
}
public static void PrintMe<T>(T[] elm)
{
Console.WriteLine("PrintMe<T>(T[] elm)");
Console.WriteLine(string.Join("", elm));
}
public static void PrintMe<T>(T elm)
{
Console.WriteLine("PrintMe<T>(T elm)");
Console.WriteLine(elm.ToString());
}
}
}
形式和PrintMe2
形式之间是有区别的。
观察这两个示例之间的区别:
PrintMe
(lambda (x) ...)
格式允许lambda接受任意数量的参数,并将所有参数放入列表中,并绑定到lambda主体中的(lambda x ...)
。即;; Example 1.
(define f
(lambda (x)
(if (list? x)
(display "x is a list!")
(display "x is not a list"))))
(f 1) ; Displays "x is not a list".
;; Example 2.
(define g
(lambda x
(if (list? x)
(display "x is a list!")
(display "x is not a list"))))
(g 1) ; Displays "x is a list!".
是参数列表。
这就是为什么当您向(lambda x ...)
提供列表(例如x
)时,x
将是g
(列表列表)。
要修改您的代码,请执行以下操作:
(g '(1 2 3))
您可以在The Racket Guide中阅读有关x
的更多信息。特别是,请参阅第4.4.1节(声明休止符)。
答案 1 :(得分:0)
我认为在空列表中调用过程时,提高error
会更好–
(define last-element-of-list
(lambda (l)
(cond ((null? l)
(error 'last-element-of-list "cannot get last element of empty list"))
((null? (cdr l))
(car l))
(else
(last-element-of-list (cdr l))))))
(last-element-of-list '(1)) ;; 1
(last-element-of-list '(1 2)) ;; 2
(last-element-of-list '(1 2 3)) ;; 3
(last-element-of-list '(1 2 3 4)) ;; 4
(last-element-of-list '()) ;; error: cannot get last element of empty list