gpt4 book ai didi

f# - 如何在F#中编写类似ZipN的函数?

转载 作者:行者123 更新时间:2023-12-04 16:48:08 25 4
gpt4 key购买 nike

我想创建一个带有签名seq<#seq<'a>> ->seq<seq<'a>>的函数,该函数的行为类似于Zip方法,它接收任意数量的输入序列的序列(而不是Zip2和Zip3中的2或3),并返回序列序列而不是元组。

也就是说,给定以下输入:

[[1;2;3];
[4;5;6];
[7;8;9]]

它将返回结果:
[[1; 4; 7];
[2; 5; 8];
[3; 6; 9]

除了使用序列而不是列表。

我是F#的新手,但是我创建了一个函数,该函数可以实现我想要的功能,但是我知道可以对其进行改进。它不是尾递归,而且看起来可能更简单,但是我还不知道如何。我还没有找到一种在没有第二个功能的情况下以我想要的方式(例如接受 int list list作为输入)获得签名的好方法。

我知道可以直接使用枚举器实现此功能,但是我对以功能方式实现此功能很感兴趣。

这是我的代码:
let private Tail seq = Seq.skip 1 seq
let private HasLengthNoMoreThan n = Seq.skip n >> Seq.isEmpty

let rec ZipN_core = function
| seqs when seqs |> Seq.isEmpty -> Seq.empty
| seqs when seqs |> Seq.exists Seq.isEmpty -> Seq.empty
| seqs ->
let head = seqs |> Seq.map Seq.head
let tail = seqs |> Seq.map Tail |> ZipN_core
Seq.append (Seq.singleton head) tail

// Required to change the signature of the parameter from seq<seq<'a> to seq<#seq<'a>>
let ZipN seqs = seqs |> Seq.map (fun x -> x |> Seq.map (fun y -> y)) |> ZipN_core

最佳答案

let zipn items = items |> Matrix.Generic.ofSeq |> Matrix.Generic.transpose

或者,如果您真的想自己写:

let zipn items = 
let rec loop items =
seq {
match items with
| [] -> ()
| _ ->
match zipOne ([], []) items with
| Some(xs, rest) ->
yield xs
yield! loop rest
| None -> ()
}
and zipOne (acc, rest) = function
| [] -> Some(List.rev acc, List.rev rest)
| []::_ -> None
| (x::xs)::ys -> zipOne (x::acc, xs::rest) ys
loop items

关于f# - 如何在F#中编写类似ZipN的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11770441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com