F#检查列表是否为空

时间:2018-09-17 10:51:35

标签: f# functional-programming

作为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'

我的解决方案工作正常,但是当我给index参数提供的值大于列表大小并且当我给一个空列表作为参数时,两种情况都处于相同的条件,即

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

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

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:4)

一种用于检查 global 前提条件的模式是嵌套函数,即先检查前提条件,然后再开始执行 actual 工作。这样,递归函数变得更简单,并且不需要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

更新

您可以使用if List.isEmpty list then failwith "list is empty"match list with [] -> failwith "..." | _ -> ()代替if list = [] then failwith "..."或{{1}},后者仅适用于支持相等性的元素列表。