4

假设我有一些代码:

let listB = [ 1; 2; 3 ]  

使用 Lisp 表示法,我如何做一个carcadr反对这个列表?我知道缺点是::

或者在Scheme中,firstrest

4

3 回答 3

6

List.hd 和 List.tl 会做你想做的事——但在 F# 中你会发现列表通常是使用模式匹配来解构的。例如,在以下函数中,x 匹配头部,xs 匹配传递给函数的列表的尾部:

let list = [1;2;3]

let rec f = function
    | [] -> 1
    | (x::xs) -> x * (f xs)

f list;
于 2008-11-12T09:07:30.757 回答
5

List.head:返回非空列表的第一个元素(列表的头部)

List.tail:返回非空列表的所有元素,除了第一个(列表的尾部或其余部分)

示例(使用 F# 交互式控制台):

> let sample = [1;2;3;4];;

val sample : int list

> List.head sample;;

val it : int = 1

> List.tail sample;;

val it : int list = [2; 3; 4]
于 2008-11-12T06:40:23.690 回答
2

我将不得不同意 simonuk。虽然,就像 CMS 提到的那样,hd并且tl 是正确的功能,但还有更多的争论。

使用模式匹配时,您可以利用编译器捕获您可能错过的(基本)情况的能力(例如当列表为空时)。您绝对可以捕获或继续抛出该异常,但您不必这样做,如果这种期望不经常发生,您可能会引入错误。因此,养成利用模式匹配的习惯是一种很好的编程实践。hd出于所有意图和目的,调用/ tlIS 匹配模式时应用的实际功能。实际上,在 ocaml 中,这是一个失败:

let hd = function [] -> failwith "hd" | a::l -> a
let tl = function [] -> failwith "tl" | a::l -> l

举个例子,我们可能会发现使用它更令人满意,而不是使用异常/失败options

> let car = function | hd::tl -> Some hd | _ -> None
> let cdr = function | hd::[] -> None | hd :: tl -> Some tl | _ -> None

另外,要小心使用_来匹配任何东西。当您决定添加另一种类型时,它对变体类型的伤害更大……哎呀!

于 2008-11-12T15:47:00.870 回答