【问题标题】:F# Test if element is in list using List.FoldF# 使用 List.Fold 测试元素是否在列表中
【发布时间】:2016-01-24 01:31:15
【问题描述】:

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

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

但是,我在 a=elementToFind 或 b 处遇到语法错误,表示该表达式应具有 'a -> 'b * 'c 但具有布尔值。总的来说,我对 F# 和函数式编程还是很陌生,因此我将不胜感激。

【问题讨论】:

    标签: lambda f# functional-programming


    【解决方案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

    【讨论】:

      【解决方案2】:

      您的代码中有太多的括号和逗号。

      要声明一个需要 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

      【讨论】:

        【解决方案3】:

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

        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
        

        【讨论】:

        • 正如 Jakub Lortz 所说; List.exists 是一个更好的选择,然后 tryFind 关于目标(知道它是否存在)并且具有相同的短路属性
        猜你喜欢
        • 2016-05-05
        • 2011-12-04
        • 1970-01-01
        • 2016-06-03
        • 1970-01-01
        • 2013-11-11
        • 2011-12-20
        • 1970-01-01
        • 2015-09-14
        相关资源
        最近更新 更多