我是函数式语言编程的新手。我正在尝试实现F#collect for list。
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]]
答案 0 :(得分:3)
这是一个尾递归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 ]
答案 1 :(得分:2)
collect
函数在函数式样式中有效实现很棘手,但您可以使用连接列表的@
运算符轻松实现它:
let rec collect f input =
match input with
| [] -> []
| x::xs -> (f x) @ (collect f xs)