当参数为空列表时,List 模块中的某些函数会失败。List.rev 就是一个例子。问题是可怕的价值限制。
我在尝试定义一个返回列表的函数时遇到了同样的问题,该列表除了最后一个元素之外的所有元素:
let takeAllButLast (xs: 'a list) =
xs |> List.take (xs.Length - 1)
该函数适用于非空列表,但处理空列表的版本失败:
let takeAllButLast (xs: 'a list) =
if List.isEmpty xs then []
else xs |> List.take (xs.Length - 1)
takeAllButLast []
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : '_a list, etc.
我尝试了几件事:使其成为内联函数,不为参数指定类型,为返回值指定类型,使函数依赖于类型参数,并使用 Option 类型获取稍后转换为列表的中间结果<'一个>。没有任何效果。
例如,这个函数有同样的问题:
let takeAllButLast<'a> (xs: 'a list) =
let empty : 'a list = []
if List.isEmpty xs then empty
else xs |> List.take (xs.Length - 1)
之前在 SO 中提出了一个类似的问题:空列表中的F# 值限制,但是当参数是空列表时,唯一的答案也会失败。
有没有办法编写一个同时处理空列表和非空列表的函数?
注意:该问题并非特定于返回列表中除最后一个元素之外的所有元素的函数。