I’m trying to sort each Position (which is a list) in a Position list. Currently I’m doint like this:
type Position = Position of list<int * Piece>
and my function:
let SortPositionList positionList : Position list =
let rec loop list =
match (list: Position list) with
| [] -> []
| hd::tl -> [List.sortBy(fun (x:(int*Piece)) -> fst x)(GetInternStruct(hd))::loop tl]
loop positionList
In my mind, this could be done by recursivelly sorting the actual head of the list and then concat it with the rest of the list, but it’s not working. The errors in this function are:
Type mismatch. Expecting a (int * Piece) list list but given a (int * Piece) list list list The type ‘int * Piece’ does not match the type ‘(int * Piece) list’, in the underlined loop tl
Type mismatch. Expecting a Position list but given a (int * Piece) list list list The type ‘Position’ does not match the type ‘(int * Piece) list list’, in the underline calling of loop, loop positionList
Hope you can help, thanks in advance
Pedro Dusso
EDIT
AList.map passing the sorting function would be a nice aproach?
SOLUTION
let SortPositionList (positionList : Position list) =
List.map (fun (Position(position)) -> List.sort(position)) positionList
As my Position struct is a (int * Piece) lst, I’m pattern matching it in the anonimous function and sorting it.
Thanks for the answers!
In general, there are two ways of doing things in F#. You can either use recursion explicitly or you can use existing functions. In your case, you need to do two things in a nested way – you need to iterate over the outer list and sort the inner lists. The sorting can be done using
List.sortByand the iteration (projection) can be done usingList.map.To correct your original approach (using recursion) – I simplfied it slightly (because you don’t need the
loopfunction – you can make the function itself recursive):The solution using existing functions (
List.map) has been already posted by JDU. I would just add that he uses partial function application – so the parameter passed toList.mapis a function. If this feels confusing, you can rewrite that using lambda function explicitly:Which could be more idiomatically written using the pipelining operator and the
fstfunction instead of explicit lambda parameter (as Brian mentioned):This means exactly the same thing as the code posted by JDU, but you may find it more readable. Finally, you can write the same thing using sequence expressions (which is perhaps the most elegant option in my opinion):
EDIT The functions as I wrote them here work with values of type
(int*Point) list listand not with the typePositions list. To change this, you need to add some wrapping and unwrapping. The recursive implementation should be:Similarly, for the
List.mapimplementation: