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