有一个矩阵转置功能:
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"
Run Code Online (Sandbox Code Playgroud)
它工作正常.
是什么(_ :: _):: _什么意思?
我不明白整个代码!
谁能解释一下?
谢谢!
我找到了答案:
(_ :: _):: _是匹配int类型列表的值的模式
如果我写:
let rec transpose (M:int list list) =
match M with
| hd::tl -> List.map List.head M :: transpose (List.map List.tail M)
| _ -> []
Run Code Online (Sandbox Code Playgroud)
它抛出一个运行时异常.高清有什么问题吗?
是的,当调用List.tail时会产生类似[[]; []; []]的东西,然后在调用List.head时抛出异常!
问题解决了!
谢谢你们!
Tom*_*cek 27
该功能不是特别易读,这可能是您混淆的原因.构造(_::_)::_是一个模式匹配的类型列表的int列表的值,表示当您获得非空列表的非空列表时应运行第一个案例.
同样的事情可以这样写.这更详细,但应该清楚这里发生了什么:
let rec transpose matrix =
match matrix with // matrix is a list<list<int>>
| row::rows -> // case when the list of rows is non-empty
match row with // rows is a list<int>
| col::cols -> // case when the row is non-empty
// Take first elements from all rows of the matrix
let first = List.map List.head matrix
// Take remaining elements from all rows of the matrix
// and then transpose the resulting matrix
let rest = transpose (List.map List.tail matrix)
first :: rest
| _ -> []
| _ -> []
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我们并不真正需要的价值row,rows,col和cols.这就是为什么原始实现取代了这些_(忽略了值,只检查列表是否可以按要求的方式分解).
在递归的情况下,我们解析矩阵,如下所示:
[ [ x; y; y ]; [ y; y ]
[ x; y; y ]; => [ x; x; x] :: transpose [ y; y ]
[ x; y; y ] ] [ y; y ]
Run Code Online (Sandbox Code Playgroud)
我希望图片让你更清楚!