在 f# 中获取列表的最后一个元素
Get the last element of a list in f#
我想获取列表的最后一个元素,我的逻辑是反转列表并获取其头部:
module Program1 =
let last list =
let newList=List.rev list;
List.head newList;
newList
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (last list )
但它给了我这个错误
Error Type mismatch. Expecting a
unit list
but given a
int list
The type 'unit' does not match the type 'int'
谁能帮帮我?
这里有很多东西要打开。
首先,你的功能不是return你想要的return。看到那里的最后一行,上面写着 newList
的那一行吗?那是您函数的 return 值。函数体的最后一行是它的 return 值。因此,您正在 returning 反向列表,而不是最后一个元素。
第二个,因为您没有returning List.head
调用的结果,所以您忽略了它。没有对那个结果做任何事情。无视。 F# 编译器试图在此处帮助您:如果您忽略了一个值,则意味着您做错了什么,如果您这样做,F# 会抱怨(发出警告)。
但该规则有一个例外:您可以忽略 unit
类型的值。逻辑是这样的,如果你有一个 unit
类型的值,你一定是通过产生副作用获得它的。因为如果没有副作用,也没有结果值(unit
表示 "no value"),那意义何在?
因此,编译器是这样认为的:如果您忽略了一个值,那么该值的类型必须是 unit
。由于 List.head newList
是 unit
类型,因此 newList
必须是 unit list
类型。因此,list
必须是 unit list
类型。因此,您的函数是 unit list -> unit list
类型(即它需要一个 unit list
作为参数,并且 return 另一个 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
我想获取列表的最后一个元素,我的逻辑是反转列表并获取其头部:
module Program1 =
let last list =
let newList=List.rev list;
List.head newList;
newList
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (last list )
但它给了我这个错误
Error Type mismatch. Expecting a
unit list
but given a
int list
The type 'unit' does not match the type 'int'
谁能帮帮我?
这里有很多东西要打开。
首先,你的功能不是return你想要的return。看到那里的最后一行,上面写着 newList
的那一行吗?那是您函数的 return 值。函数体的最后一行是它的 return 值。因此,您正在 returning 反向列表,而不是最后一个元素。
第二个,因为您没有returning List.head
调用的结果,所以您忽略了它。没有对那个结果做任何事情。无视。 F# 编译器试图在此处帮助您:如果您忽略了一个值,则意味着您做错了什么,如果您这样做,F# 会抱怨(发出警告)。
但该规则有一个例外:您可以忽略 unit
类型的值。逻辑是这样的,如果你有一个 unit
类型的值,你一定是通过产生副作用获得它的。因为如果没有副作用,也没有结果值(unit
表示 "no value"),那意义何在?
因此,编译器是这样认为的:如果您忽略了一个值,那么该值的类型必须是 unit
。由于 List.head newList
是 unit
类型,因此 newList
必须是 unit list
类型。因此,list
必须是 unit list
类型。因此,您的函数是 unit list -> unit list
类型(即它需要一个 unit list
作为参数,并且 return 另一个 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