2015-12-21 76 views
0

我試圖實現一個遊戲的RLE解碼器,它的工作原理,但我想縮小一點代碼,但我不知道如何把List.appendrepeatrleExpand電話在一行在F#中追加列表單線程

List.append的簽名是List.append : 'T list -> 'T list -> 'T list,所以很明顯,我不能只是做 List.append(repeat(pattern,count), rleExpand(tail,rleTag)) - 但想知道如何做到這一點。我也可以使用@操作 - 也許這是最可讀的一個。但我怎麼使用List.append如果我的列表是通過一個功能應用在下面的清單創建什麼樣的?

let rec repeat(item,count) = 
    match count with 
    | 0 -> [] 
    | n -> item :: repeat(item,n-1) 

let rec rleExpand(packed, rleTag: int) = 
    match packed with 
    | [] -> []  
    | tag :: count :: pattern :: tail when tag = rleTag -> 
     let repeated = repeat(pattern,count) 
     let rest = rleExpand(tail,rleTag) 
     List.append repeated rest 
    | head :: tail -> head :: rleExpand(tail,rleTag) 

回答

4

我可能會寫:

repeat(pattern,count) @ rleExpand(tail,rleTag) 

但你也可以寫

List.append (repeat(pattern,count)) (rleExpand(tail,rleTag)) 

不能使用List.append(repeat(pattern,count), rleExpand(tail,rleTag))爲您最初建議,因爲List.append需要咖喱(而不是tupled)參數。

1

做這樣的工作?

let repeat(item, count) = [for i in 1 .. count -> item] 

let rec rleExpand(packed, rleTag: int) = 
    match packed with 
    | [] -> []  
    | tag :: count :: pattern :: tail when tag = rleTag -> 
     List.collect id [repeat(pattern,count); rleExpand(tail,rleTag)] 
    | head :: tail -> head :: rleExpand(tail,rleTag) 

通過不使用元組作爲參數來使用make函數也更常見。

+1

爲了重複,最好編寫'let repeat(item,count)= List.init count(fun _ - > item)'。它可能會更快。 – jpe

+0

看起來你是對的。我只是用'count = 1000000'做了一個快速測試,'List.init'確實比理解更快。 – Shredderroy

+0

感謝您提供更好的重複功能的建議:) – Axarydax