2013-11-23 32 views
2

我需要,可以採取的參數的任意數量的功能,每一個可以是任一類型'Tseq<'T>的。在函數內部,我需要將它作爲一個單獨的seq<'T>進行處理,所有輸入的組合順序與它們提供的順序相同。如何弄平混合「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>' 

這裏有什麼問題,以及如何得到它的工作如所須?可能這可以用完全不同的方式完成?

回答

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不是必需的。

+0

最近討論了這個問題http://stackoverflow.com/a/674422/801189,實際上一個模塊可以有這樣的功能,只允許表達式不能。我仍然無法使它在FSI中工作。你有沒有試過在FSI上運行這個? –

+0

是的,它完美的工作。將代碼複製到.fsx,將其發送到fsi並在fsi中嘗試讓fl = Test.flatten(1,seq [1; 2; 3]) – Gustavo

+0

謝謝!看起來像MSDN是對的(我在鏈接的討論中是正確的)。現在它可以工作,但我仍然更喜歡一個模塊,而不是一個類型。 –

相關問題