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

V.B*_*.B. 2 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>
Run Code Online (Sandbox Code Playgroud)

但即使是最简单的情况,我也无法让它在FSI中发挥作用

let fl = Test.flatten 1;;
  ----------------------^

...: error FS0001: The type 'int' is not compatible with the type 'seq<'a>'
Run Code Online (Sandbox Code Playgroud)

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

Gus*_*Gus 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
Run Code Online (Sandbox Code Playgroud)

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

| :? seq<int> as sq -> yield! sq 
Run Code Online (Sandbox Code Playgroud)

box不是必需的.