F# 如何根据列表进行汽车和cadr?

F# 如何根据列表进行汽车和cadr?,f#,functional-programming,list,F#,Functional Programming,List,假设我有一些代码: let listB = [ 1; 2; 3 ] 使用Lisp表示法,如何根据此列表执行car和cadr?我知道cons是: 或者在Scheme中,first和rest?List.head:返回非空列表的第一个元素(列表的头) List.tail:返回列表的所有元素 除第一个(列表的尾部或其余部分)之外的非空列表 示例(使用F#交互式控制台): List.hd和List.tl会做你想做的事情——但在F#中,你会发现列表通常是使用模式匹配来解构的。例如,在以下函数中,x匹配

假设我有一些代码:

let listB = [ 1; 2; 3 ]  
使用Lisp表示法,如何根据此列表执行
car
cadr
?我知道cons是

或者在Scheme中,
first
rest

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

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

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


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

let list = [1;2;3]

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

f list;

我必须同意西蒙努克的观点。虽然,正如CMS所提到的,
hd
tl
是正确的函数,但还有更多的论点

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

let hd = function [] -> failwith "hd" | a::l -> a
let tl = function [] -> failwith "tl" | a::l -> l
例如,我们可能会发现使用
选项比使用异常/故障更令人满意:

> let car = function | hd::tl -> Some hd | _ -> None
> let cdr = function | hd::[] -> None | hd :: tl -> Some tl | _ -> None
另外,要小心使用
\uu
匹配任何内容。当您决定添加另一个类型时,在变体类型中会受到更大的伤害。。。哎呀

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