【问题标题】:Implementing collect for list in F#在 F# 中为列表实现收集
【发布时间】:2014-11-10 01:59:52
【问题描述】:

我是函数式语言编程的新手。我正在尝试实现 F# 收集列表。

let rec collect func list =
     match list with
     | [] -> []
     | hd::tl -> let tlResult = collect func tl 
                 func hd::tlResult;;

collect (fun x -> [for i in 1..3 -> x * i]) [1;2;3];;

应该打印:

val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]

但我得到了:

val it : int list = [[1; 2; 3;], [2; 4; 6;], [3; 6; 9]]

【问题讨论】:

    标签: list f# functional-programming collect


    【解决方案1】:

    这是一个尾递归 collect,它不会对大型列表进行堆栈溢出。

    let collect f xs =
        let rec prepend res xs = function
            | [] -> loop res xs
            | y::ys -> prepend (y::res) xs ys
        and loop res = function
            | [] -> List.rev res
            | x::xs -> prepend res xs (f x)
        loop [] xs
    

    一个更简单的版本,有点作弊,是:

    let collect (f: _ -> list<_>) (xs: list<_>) = [ for x in xs do yield! f x ]
    

    【讨论】:

      【解决方案2】:

      collect 函数很难以函数式风格高效实现,但您可以使用连接列表的 @ 运算符轻松实现它:

      let rec collect f input =
        match input with
        | [] -> []
        | x::xs -> (f x) @ (collect f xs)  
      

      【讨论】:

      • 非常感谢,我忘了@运算符。 (:
      猜你喜欢
      • 2011-08-01
      • 1970-01-01
      • 2021-12-31
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多