F#代码有什么问题?

What is wrong in F# code?

在 F# 中,我试图获取给定列表的最后一个元素。我写了下面的代码

let rec findLast t =
    match t with
        | hd :: [] -> hd
        | hd :: tl -> findLast tl
        | _ -> -1

printfn "%A" (findLast [1,2,3,4,5])

但是当我尝试在 F# Interactive 中执行它时,它会抱怨如下

error FS0001: This expression was expected to have type int but here has type 'a * 'b * 'c * 'd * 'e

我只是想知道上面的代码有什么问题。我知道有多种智能和优雅的方法可以从 F# 中的列表中获取最后一个元素。但我很想知道上面的代码有什么问题?

试试这个:

let rec lastElem = function
    | []    -> None
    | [x]   -> Some x
    | x::xs -> lastElem xs

你可以在REPL中试试:

> lastElem [1;2;3];;

val it : int option = Some 3

> lastElem ["a";"b";"c"];;

val it : string option = Some "c"

1,2,3,4,5 是一个元组。 'a * 'b * 'c * 'd * 'e 是元组定义。创建一个带分号的列表 [1;2;3;4;5][1,2,3,4,5] 是一个元组列表,其中一项是五元组。

let rec findLast t =
    match t with
        | hd :: [] -> hd
        | hd :: tl -> findLast tl
        | _ -> -1

printfn "%A" (findLast [1;2;3;4;5])

正如@Phillip-Scott-Givens 所指出的,您可能犯了一个完全常见的错误(尤其是对于 C# 用户而言),并使用逗号而不是分号来分隔列表。

这会生成元组列表 [(1, 2, 3, 4, 5)] 而不是整数列表 [1;2;3;4;5]。在你的类型定义中出现意想不到的星号就是一个症状:)

也就是说,这里有一些不同的函数可以从元组、列表和元组列表中获取最后一个值(参考:):

// Data: 
let tuples = [ (1,2,3,4,5); ]      // = [1,2,3,4,5]
let firstListElement = tuples.[0]  


// Access: 
let rec lastItemInList = function
    | hd :: [] -> hd
    | hd :: tl -> lastItemInList tl
    | _ -> failwith "Empty list."
let lastValueOfFirstItem = function
    | (_, _, _, _, last) :: _ -> last
    | _ -> -1
let lastValueOfTuple = function _, _, _, _, last -> last
// same as: let lastValueOfTuple myTuple = 
//              match myTuple with
//              | (_, _, _, _, last) -> last


// Examples:
tuples |> lastItemInList              // val it : int * int * int * int * int = (1, 2, 3, 4, 5)
tuples |> lastValueOfFirstItem        // val it : int = 5
tuples |> List.map lastValueOfTuple   // val it : int list = [5]
firstListElement |> lastValueOfTuple  // val it : int = 5