2015-12-21 39 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