There is a Matrix transpose function:
let rec transpose = function
| (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M)
| _ -> []
[[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] |> transpose |> printfn "%A"
It works fine.
What does ( _ :: _ ) :: _ mean?
I don't understand the whole code!
Who can explain it?
Thank You!
I find the answer:
( _ :: _ ) :: _ is a pattern matching on value of type list of lists of ints
If i write:
let rec transpose (M:int list list) =
match M with
| hd::tl -> List.map List.head M :: transpose (List.map List.tail M)
| _ -> []
It throw an runtime exception. Is there something wrong with hd?
Yes, it make something like [ [ ];[ ];[ ] ] when call List.tail, then it throws exception when call List.head!
Problem Solved!
Thank you all!
I'm sorry for bumping an outdated thread, but your original answer is almost right. The only thing that's wrong is the termination condition for an empty list. The code should look something like this:
This maps
head
over the lists to extract the first column and uses that to form the first row prepended to the result of transposing the remaining columns.The function is not particularly readably written, which may be the reason for your confusion. The construct
(_::_)::_
is a pattern matching on value of type list of lists of ints that says that the first case should be run when you get a non-empty list of non-empty lists.The same thing can be written like this. This is more verbose, but it should be clear what is going on here:
As you can see, we don't really need the values
row
,rows
,col
andcols
. That's why the original implementation replaces these with_
(which ignores the value and only checkes that the list can be decomposed in the required way).In the recursive case, we deconstruct the matrix like this:
I hope that the picture makes it more clear for you!
This may also help you:
Understanding a Matrix transposition Function in Haskell
It is a very similar function in a similar programming language (Haskell).
(_::_)::_
is pattern matching._
is simply an unused variable. This would be equivalent: