合并OCaml中的列表列 [英] Combining a column of lists in OCaml

查看:47
本文介绍了合并OCaml中的列表列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想本质上在OCaml中转置矩阵(不使用递归或任何形式的循环)

I want to essentially transpose a matrix in OCaml (without using recursion or any sort of looping)

例如,如果我具有以下矩阵:[[1;2];[3;4]]
我想得到[[1;3];[2;4]]的输出.

For example, if I have the following matrix: [[1;2];[3;4]],
I want to have the output of [[1;3];[2;4]].

到目前为止,我所做的是将原始矩阵分为几列:

What I have done so far is break the original matrix into individual columns:

//function that separates into cols
let separate li =
    List.map (fun x -> [x]) li;;

我从另一个函数中调用此辅助函数:

I call this helper function from another function:

let trans x = 
    List.concat (List.map separate li) x;;

我当时以为这将以我想要的方式合并所有列,但最终以以下输出结束:[[1];[2];[3];[4]].

I was thinking this would combine all the columns the way I want to but rather, ended with the following output: [[1];[2];[3];[4]].

推荐答案

假设您的列表列表为矩形,则

Assuming your list of lists is rectangular, this Standard ML code translates to OCaml as such:

let rec transpose xss =
    match xss with
        | [] -> []
        | []::_ -> []
        | _ -> List.map List.hd xss :: transpose (List.map List.tl xss)

它将提取第一列(List.map List.hd xss),然后在删除已提取的列(List.map List.tl xss)之后将其与其余列的提取递归组合.

It extracts the first column (List.map List.hd xss) and recursively combines it with the extraction of the remaining columns, after having removed the already extracted column (List.map List.tl xss).

此功能中仍然保留的显式递归不能轻易地被映射/折叠所替代,因为它们将一次寻址一行,而上面的递归方案会一次寻址所有行(一部分). 展开/变形 可能会让您更加幸运:

The explicit recursion that still remains in this function cannot easily be replaced by mapping / folding, since those would address one row at a time, where the recursion scheme above addresses (a part of) all rows at once. You might have more luck with unfolding / anamorphism:

let rec unfold f a =
    match f a with
    | Some (b, a') -> b :: unfold f a'
    | None -> []

val unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list = <fun>

其中'a可能是您的输入行矩阵和'b矩阵列的逐渐减少:

where 'a could be the gradual reduction of your input row matrix, and 'b the matrix columns:

let transpose =
    unfold (function
            | [] -> None
            | []::_ -> None
            | m -> Some (List.map List.hd m, List.map List.tl m))

这篇关于合并OCaml中的列表列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆