我需要一个可以接受任意数量参数的函数,每个参数可以是'T
或seq<'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>'
这里有什么问题以及如何根据需要使其工作?可能这可以用一些完全不同的方式来完成吗?
答案 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
。