【发布时间】:2018-05-14 21:48:56
【问题描述】:
当参数为空列表时,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# value restriction in empty list 中提出了类似的问题,但当参数为空列表时,唯一的答案也会失败。
有没有办法编写一个同时处理空列表和非空列表的函数?
注意:这个问题并不特定于返回列表中除最后一个元素之外的所有元素的函数。
【问题讨论】:
标签: list f# value-restriction