joe*_*sid 4 .net f# reverse function 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 )
Run Code Online (Sandbox Code Playgroud)
但它给了我这个错误
Error Type mismatch. Expecting a
unit list
but given a
int list
The type 'unit' does not match the type 'int'
Run Code Online (Sandbox Code Playgroud)
谁能帮帮我吗?
在这里拆包有很多东西.
首先,您的功能不会返回您想要返回的内容.看那最后一行,那个说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
一个函数传递给一个带有a的函数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
Run Code Online (Sandbox Code Playgroud)
此外,还有一个现成的功能List.last
,你可以使用(除非这是作业,在这种情况下你应该在问题中提到).
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (List.last list)
Run Code Online (Sandbox Code Playgroud)
但要注意,列表中可能没有最后一个元素 - 如果列表为空.在这种情况下,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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1170 次 |
最近记录: |