【问题标题】:F# Check if a list is emptyF# 检查列表是否为空
【发布时间】:2018-09-18 02:31:24
【问题描述】:

作为一个 F# 新手,我正在尝试实现一个简单的函数,该函数将索引和列表作为参数,然后返回给定索引的列表值。

let rec getElementAtIndex (index : int) (list : 'a list) = 
  match index, list with
    | _ ,[] -> failwith "index is greater than number of elements in list.."
    | _, _ when index < 0 -> failwith "index is less than 0." 
    | 0, (first::_) -> first
    | _, (_::rest') -> getElementAtIndex (index - 1) rest'

我的解决方案工作正常,但是当我给出的索引参数大于列表大小并且当我给出一个空列表作为参数时,在这两种情况下都会进入相同的条件,即

| _ ,[] -> failwith "index is greater than number of elements in list."

在不使用 .net 库方法的情况下,如何避免这种情况并检查列表是否为空并且给定的索引是否大于列表大小?

任何帮助将不胜感激

【问题讨论】:

  • 两种情况下的错误信息看起来都是正确的。有什么问题?
  • 我认为检查列表是否为空和检查给定索引是否超出范围是不同的事情。
  • 如果您对遍历列表以确定其长度的低效率感到满意,您可以使用List.length
  • @molbdnilo 有没有办法在没有库函数的情况下做到这一点?
  • 自己写length很简单。

标签: f# functional-programming


【解决方案1】:

检查全局先决条件的模式是嵌套函数,即先检查先决条件,然后开始递归实际工作。这样,递归函数就变得更简单了,不需要when 守卫或length

let getElementAtIndex index list =
  if index < 0 then failwith "index is less than 0"
  if List.isEmpty list then failwith "list is empty"
  let rec get = function
    | _ , [] -> failwith "index is greater than number of elements in list"
    | 0, first::_ -> first
    | _, _::rest -> get(index - 1, rest)
  get(index, list)

function 语法是:

  let rec get i l =
    match i, l with
    | _ , [] -> failwith "index is greater than number of elements in list"
    | 0, first::_ -> first
    | _, _::rest -> get (index - 1) rest

更新

您可以使用match list with [] -&gt; failwith "..." | _ -&gt; ()if list = [] then failwith "..." 而不是if List.isEmpty list then failwith "list is empty",后者仅适用于支持相等的元素列表。

【讨论】:

  • 我已经在我的解决方案中做到了。我希望能够在不使用 .net 库中的辅助函数的情况下检查给定的列表参数是否为空列表。
  • @Tartar,此解决方案可以区分您要求的错误情况。这里根本没有使用 .NET 函数。如果isEmpty 属性是反对的原因,那实际上是对实际空列表的简单匹配,请参阅github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2010-09-07
相关资源
最近更新 更多