惯用F#un-pairwise?

时间:2014-06-06 16:06:56

标签: f# sequence

我们可以使用seq<float>seq<float * float>转到Seq.pairwise

但是如果给出一系列同质元组,我该如何回到序列?

我考虑了

someSeq |> Seq.map (fun a b -> seq { yield a; yield b })

但这给了我签名

seq<float * float> -> seq<(float * float -> seq<float * float>)>

我觉得我错过了什么......

4 个答案:

答案 0 :(得分:5)

尝试使用Seq.collect并将元组作为参数:

someSeq |> Seq.collect (fun (a, b) -> seq { yield a; yield b })

Daniel 注意:

someSeq |> Seq.collect (fun (a, b) -> [a; b])

但请注意,这与'un-pairwise'不完全相同,因为Seq.pairwise将为原始列表中的每个相邻元素对生成一个元素。注意:

let a = [1..5]
let b = a |> Seq.pairwise
let c = b |> Seq.collect (fun (a, b) -> [a; b])

// c = [1; 2; 2; 3; 3; 4; 4; 5]

要真正“成对”成对序列,您可以执行以下操作(接受并返回seq):

let unpairwise (x) = 
    seq {
        if not(Seq.isEmpty x) then
            let (a, b) = Seq.head x
            yield a
            yield b
            yield! Seq.skip 1 x |> Seq.map (fun (a, b) -> b)
    }

或者像这样(接受seq,但返回list):

let unpairwise (x) = 
    if Seq.isEmpty x then
        []
    else
        let (a, b) = Seq.head x
        [ a; b ] @ [ for (a, b) in Seq.skip 1 x -> b ]

或者甚至可能是这样(接受并返回list):

let unpairwise (x) = 
    match x with
    | (a,b)::t -> [ a; b ] @ [ for (a, b) in t -> b ]
    | _ -> [] 

答案 1 :(得分:4)

在这种情况下,序列表达式会更加惯用。

seq { for x, y in someSeq do yield x; yield y }

您的函数采用两个参数而不是一个元组。只有一个参数传递给这个lambda函数,但由于它需要两个,它返回一个带有缺失参数的新函数。

someSeq |> Seq.map(fun (a, b) -> seq { yield a; yield b })

这会给<seq<seq<float>>。您可以使用seq<float>转到Seq.concat

someSeq |> Seq.map(fun (a, b) -> seq { yield a; yield b }) |> Seq.concat

Seq.collect合并了Seq.mapSeq.concat

someSeq |> Seq.collect(fun (a, b) -> seq { yield a; yield b })

这里是关于将部分参数传递给函数的MSDN F#文档的剪辑。

  

Partial Application of Arguments

     

如果提供的参数少于指定数量,则创建   一个期望剩余参数的新函数。这种方法   处理参数被称为currying并且是一个特征   像F#这样的函数式编程语言。

答案 2 :(得分:1)

我认为您可能打算将a b作为(a, b)的元组?否则,a是元组,您将部分应用;映射到期望另一个元组的函数序列(因此float * float -> seq<float * float>签名)。非常混乱!

然后,您可能希望使用Seq.concat展平序列序列,或者使用Seq.collect而不是map来开始。

这样做你想要的吗?这仍然不是Seq.pairwise的倒数。不确定这是不是你想要的......

答案 3 :(得分:1)

如果您需要将成对结构转换为原始列表,为什么不只是

let pw = Seq.pairwise { 1 .. 5 } //seq [(1, 2); (2, 3); (3, 4); (4, 5)]
let up = unpairwise pw |> Seq.toList //[ 1; 2; 3; 4; 5 ]

示例:

{{1}}