F#使用List.Fold测试元素是否在列表中

时间:2015-10-24 16:30:19

标签: lambda f# functional-programming

我正在尝试编写一个函数,该函数接受列表和元素在该列表中查找,如果元素在列表中则返回true,否则返回false。我想使用List.Fold使函数更短。现在它看起来像这个

let isInList(elementToFind, listToCheck) = 
    List.fold(fun(a, b) -> a=elementToFind or b), false, listToCheck;

但是,我在= elementToFind或b时遇到语法错误,说该表达式预计会有'a - > 'b *'c但是有bool。我对F#和一般的函数式编程都很陌生,所以我能得到的任何帮助都会非常感激。

3 个答案:

答案 0 :(得分:1)

您可以使用List.fold实现此目的,如下所示:

let isInList elementToFind listToCheck = 
    List.fold(fun acc x -> acc || x = elementToFind) false listToCheck

示例:

let x = [1;2;2;3]
let y = 4
let z = 2

isInList y x |> printfn "%A"
isInList z x |> printfn "%A"

打印:

false
true

链接:

https://dotnetfiddle.net/6swKR5

Read more about List.fold

答案 1 :(得分:1)

代码中的括号和彗星太多了。

要声明一个带2个参数的函数,你应该使用

let f param1 param2 = ...

没有括号,没有昏迷。如果将函数定义为

let f2 (param1, param2) = ...

你定义一个带有1个参数的函数,这个参数是一个2元素的元组。

从代码中删除所有逗号和几乎所有括号将再次出错 - 您传递给List.fold的函数的参数顺序错误。

let isInList elementToFind listToCheck = 
    List.fold(fun acc elem -> elem=elementToFind || acc) false listToCheck

您还应该查看List module的文档。那里有许多有用的功能,例如List.exists

答案 2 :(得分:0)

当需要性能时,最好使用tryFind,因为fold是非短路的。 这意味着如果列表是1兆。如果元素为long,则会搜索第一个元素,折叠将一直运行到列表的末尾。

let isInList elementToFind listToCheck = 
    List.tryFind ((=) elementToFind) listToCheck

let x = [1;2;2;3]
let y = 4
let z = 2

isInList y x |> printfn "%A"    // None    
isInList z x |> printfn "%A"    // Some 2