如何展平混合'T和seq<'T>的输入单个seq<'T>

时间:2013-11-23 18:12:28

标签: f# f#-interactive

我需要一个可以接受任意数量参数的函数,每个参数可以是'Tseq<'T>类型。在函数内部,我需要将它作为单个seq<'T>处理,所有输入的组合顺序与它们提供的顺序相同。

显而易见的方法是:

module Test =
    let flatten ([<ParamArray>] args) =
        let flat = seq {
                for a in args do
                    match box a with
                    | :? int as x -> yield x
                    | :? seq<int> as sq -> 
                        for s in sq do
                            yield s
                    | _ -> failwith "wrong input type"
                }
        flat // this should be seq<int>

但即使最简单的情况

,我也无法在FSI中运行
let fl = Test.flatten 1;;
  ----------------------^

...: error FS0001: The type 'int' is not compatible with the type 'seq<'a>'

这里有什么问题以及如何根据需要使其工作?可能这可以用一些完全不同的方式来完成吗?

1 个答案:

答案 0 :(得分:5)

来自msdn

  

在F#中,参数数组只能在方法中定义。他们不可能   用于独立函数或定义的函数   模块。

因此,使用静态方法声明类型而不是模块。

open System
type Test() =
    static member flatten ([<ParamArray>] args: obj[]) =
        let flat = seq {
                for a in args do
                    match box a with
                    | :? int as x -> yield x
                    | :? seq<int> as sq -> 
                        for s in sq do
                            yield s
                    | _ -> failwith "wrong input type"
                }
        flat

如果您有其他let绑定,您仍然可以声明具有相同名称的模块。 另请注意,在比赛的第二个后卫中,您可以通过执行以下操作来避免for循环:

| :? seq<int> as sq -> yield! sq 

并且不需要box