2017-03-05 67 views
3

F#可以很容易地解開元組。拆箱清單也是可行的,但編譯器發出警告:我可以在沒有警告的情況下解壓F#列表嗎?

let m = [1; 2; 3] 
let [a; b; c] = m 
// Incomplete pattern matches on this expression. For example, the value '[_;_;_;_]' may indicate a case not covered by the pattern(s) 

有沒有辦法避免這種警告?

回答

5

您可以使用#nowarn指令(在您的案例中爲#nowarn "25")禁用每個文件的警告,或者您可以使用--nowarn禁用命令行上的警告。

查看詳情F# Compiler Directives

當第一次禁用時,目前沒有辦法再次重新啓用警告。

您的匹配可能(意外),導致運行時錯誤,如果元件的數量不能解壓到[a;b;c],因此,你可以使用一個完全匹配是明確有關RISC:

let m = [1;2;3] 
let (a,b,c) = 
    match m with 
    | [a;b;c] -> (a,b,c) 
    | _ -> failwith "Expected exactly three items in m" 
1

一個明顯,但幾乎沒有優雅的,方法是:

let m = [1; 2; 3] 
let a = List.item 0 m 
let b = List.item 1 m 
let c = List.item 2 m 

你可以寫一個輔助函數,使之整潔:

let unpack3 x = (List.item 0 x, List.item 1 x, List.item 2 x) 

let (a, b, c) = unpack3 m 

基本上,list不是很適合,如果你知道你總是會有一個固定數量的項目。

+1

在這種情況下,你對某個列表不太適合。在我的「現實生活」代碼中,列表由List.map生成。有一種更簡單的方法將列表轉換爲元組嗎?像Tuple.ofList()? – Soldalma

+0

爲什麼不「let myTuple = myList。[0],myList。[1],myList。[2]」?如果這還不夠好,也許你試圖以不太好的方式解決問題。 –

+1

@Soldalma - 它不適合類型系統,因爲返回類型(例如2元組,3元組...)將取決於列表的內容。 –

4

如果您的清單m有2個或4個元素會發生什麼?

顯然有一種方式,普通的舊模式匹配:

let a, b, c = 
    match m with 
    | [a;b;c] -> a,b,c 
    | _ -> ... // handle the length!=3 case 

F#允許你解構右側對象時,有明確的,你只需要支付一個案例的方式。這是元組的情況,因爲只有一個元組類型可以匹配左側和右側。像這樣的東西顯然不會編譯,因爲類型不匹配:

let m = 1, 2 

let a, b, c = m 

然而,在你的情況有沒有保證,你是不是其實在這樣的場景:

let m = [ 1; 2 ] 

let [1;2;3] = m 

你」實際上要求編譯器允許非窮舉的模式匹配。您可以按照其他答案中的說明禁用警告,但是您以這種方式邀請運行時錯誤。

相關問題