Reputation: 16603
I'm trying to implement a RLE decoder for a game, and it works, but I'd like to shrink the code a bit, but I can't figure out how to put List.append
and the repeat
and rleExpand
calls on one line
The signature of List.append is List.append : 'T list -> 'T list -> 'T list
, so obviously I cannot just do
List.append(repeat(pattern,count), rleExpand(tail,rleTag))
- but would like to know how to do that. I also can use the @ operator - maybe that's the most readable one. But how do I use List.append if my lists are created by a function application like in the listing below?
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)
Upvotes: 0
Views: 720
Reputation: 12184
I would probably write:
repeat(pattern,count) @ rleExpand(tail,rleTag)
But you can also write
List.append (repeat(pattern,count)) (rleExpand(tail,rleTag))
You cannot use List.append(repeat(pattern,count), rleExpand(tail,rleTag))
as you originally suggested because List.append
takes curried (rather than tupled) arguments.
Upvotes: 4
Reputation: 2920
Does something like this work?
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)
It's also more commonplace to use make functions curryable by not using tuples as parameters.
Upvotes: 1