2015-08-21 47 views
2

有F#內置運算符/函數,它允許解壓參數列表/元組並將其傳遞給函數調用?F# - 圖示/解包參數列表

用法示例:

// simple add function 
let add (a1 : int) (a2 : int) (a3 : int) = a1 + a2 + a3 

// what I want to achieve 
let result = add (missing_operator)[1; 2; 3] 

// or 
let result' = add (missing_operator) (1, 2, 3) 

// flattening list 
let a = [1; 2; 3] 
let b = [(missing_operator) a; 4; 5] 

類同Python的*操作

def add(a1, a2, a3): 
    return a1 + a2 + a3 

add(*[1,2,3]) 

或應用(FUNC_NAME,args_list)功能

apply(add, [1, 2, 3]) 
+0

可能相關:http://stackoverflow.com/q/30622850/126014 –

回答

3

我想的慣用方法可以做到這樣一個在F#可能是這樣的:

// simple add function 
    let add (a1 : int) (a2 : int) (a3 : int) = a1 + a2 + a3 

    // what I want to achieve 
    let result = match [1; 2; 3] with | [a;b;c] -> add a b c // pattern matching works on lists 

    // or 
    let result' = let (a,b,c) = (1, 2, 3) in add a b c // unpacking tuples 

    // flattening list 
    let a = [1; 2; 3] 
    let b =       // sequence expressions with yield! 
    seq { 
     yield! a 
     yield 4 
     yield 5 
     } |> Seq.toList 

    let c = [4; 5] 
    let b' = 
    seq { 
     yield! a 
     yield! c 
     } |> Seq.toList 
6

對於對與黑社會有預定義的運營商||><|||||><|||類似於|><|單個參數(monuple):

let add a b c = a + b + c 

add <||| (1, 2, 3) 
(1, 2, 3) |||> add 

您可以添加這樣的運營商自己:

let (||||>) (a1, a2, a3, a4) func = func a1 a2 a3 a4 

let foo u v x y = (u + v) * (x + y) 
(1, 2, 3, 4) ||||> foo 

所有這些操作符也適用於非統一類型。

如果你不想放棄類型安全,下面的作品(非空參數):

let invokeWith args op = 
    let func = op.GetType().GetMethod("Invoke", args |> Array.map(fun a -> a.GetType())) 
    func.Invoke(op, args) 

add |> invokeWith [|1; 2; 3|] 

這也適用於非均勻參數類型:

let pad (a : string) l = a.PadRight(l) 
pad |> invokeWith [| "a"; 12 |] 

中當然,一旦你放棄靜態類型檢查,你對你自己:

// does not compile 
// ("a", None) ||> pad 
+0

如果函數採用不同類型的參數會怎樣?例如:'let pad(a:string)l = a.PadRight(l)' – lad2025

+0

@ lad2025參見編輯答案 – CaringDev