这里有很多东西要解压。
首先,您的函数没有返回您希望它返回的内容。看到最后一行,上面写着newList 吗?那是你的函数的返回值。函数体的最后一行是它的返回值。因此,您返回的是反向列表,而不是最后一个元素。
第二,由于您没有返回List.head 调用的结果,因此您忽略它。没有做任何事情的结果。无视。 F# 编译器在这里试图帮助你:如果你忽略了一个值,这意味着你做错了,如果你这样做,F# 会抱怨(发出警告)。
但该规则有一个例外:您可以忽略 unit 类型的值。逻辑是,如果你有一个unit 类型的值,你一定是因为产生了副作用而获得了它。因为如果没有副作用,也没有结果值(unit 表示“没有价值”),那么重点是什么?
因此,编译器会这样思考:如果您忽略了一个值,那么该值必须是unit 类型。由于List.head newList 是unit 类型,那么newList 必须是unit list 类型。因此,list 必须是 unit list 类型。因此,您的函数是 unit list -> unit list 类型(即,它接受 unit list 作为参数并返回另一个 unit list 作为结果)。
而且由于您试图将 int list 传递给采用 unit list 的函数,编译器无法忍受:Expecting a unit list but given a int list。
最后,为了得到最后一个值而反转列表是非常浪费的!您正在重新分配大量您并不真正需要的内存。实现这一点的一种不那么浪费的方法是使用递归。可以这样想:单元素列表的最后一个元素是那个元素,而较长列表的最后一个元素是其尾部的最后一个元素。我们可以直接在 F# 中编写:
let rec last list =
match list with
| [x] -> x // The last element of one-element list is the one element
| _::tail -> last tail // The last element of a longer list is the last element of its tail
| _ -> failwith "Empty list" // Otherwise fail
另外,还有一个现成的函数List.last,你可以直接使用(除非这是家庭作业,在这种情况下你应该在问题中提及)。
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (List.last list)
但请注意,如果列表为空,则列表中可能没有最后一个元素。在这种情况下,List.last(以及List.head)会崩溃并出现异常,这通常不是一个好主意。如果您需要处理空列表的情况,请查看List.tryLast:
let mainP1()=
let list= [1; 2; 3]
match List.tryLast list with
| Some x -> printfn "Ultimul element al listei %A este %A" list x
| None -> printfn "Lista %A este goală" list