2015-09-23 81 views
2

有什麼辦法可以獲取元組的長度。 我的意思是讓a=(1,2,3)。我必須得到3F#:獲取元組的長度

我已經使用下面的代碼將元組轉換爲列表並嘗試獲取列表的長度,但結果有option類型,我無法使用它。

let tupleToList t = 
    if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) 
     then Some (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList) 
     else None 
+0

與目前的做法(一個簡單的解決方案可能是最好的)是消除或解開正在引入的'選擇'; (例如,返回一個非元組的0或-1,否則返回列表的長度),或者在使用地點(例如將它視爲'可能代表或不代表列表'的任何選項)。 – user2864740

+2

首先,元組的*長*在它的類型中是含蓄的 - 這就是爲什麼你不能獲得像這樣的函數而沒有反射*欺騙*(或其他一些運行時作弊;)) - 但在這種情況下,一個簡單的'tupleToList> >如果你對這個函數的輸入不是一個元組,那麼Option.map(List.length)'會給你'一些長度爲l和tuple的元組。 – Carsten

回答

3

如果你的目的只是爲了讓元組的長度對於任何元組的參數和一些其他的區分就像數爲0非元組參數,那麼就沒有必要與轉換元組一共列出打擾;直接

let tupleLength t = 
    if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) 
    then (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.length) 
    else 0 

給你這樣的簽名:tupleLength: t:'a -> int

測試它在FSI:

> (1,'a',10.0) |> tupleLength;; 
val it : int = 3 

> ("a",["b";"c";"d"]) |> tupleLength;; 
val it : int = 2 

["a","b","c","d"] |> tupleLength;; 
val it : int = 0 
3

由於這裏給出的tupleToList函數返回obj list option,所以你將不得不應對None情況。

非元組有多長?

爲了說明起見,我們將該長度設置爲0。在這種情況下,您可以使用Option.mapOption.fold來獲取元組的長度(以及其他值)。示例:

> (1, "2") |> tupleToList |> Option.map List.length |> Option.fold (+) 0;; 
val it : int = 2 

> ("1", 2, 3.0) |> tupleToList |> Option.map List.length |> Option.fold (+) 0;; 
val it : int = 3 

> "Not a tuple" |> tupleToList |> Option.map List.length |> Option.fold (+) 0;; 
val it : int = 0 

如果您願意,可以將表達式Option.map List.length |> Option.fold (+) 0綁定到函數。

0

假設它總是發送元組我認爲以下更簡單。

let t = 1,2,3 


let inline countTuples t = 
t.GetType().GetGenericArguments().Length 

countTuples t 
//val it : int = 3 

let a = 4 

countTuples a 
//val it : int = 0 

let list = ["4", "5"] 

countTuples list 
//val it : int = 1 

如果不總是元組,並可能有通用的參數(最後一個例子),那麼元組檢查是必要的,當然......不管它