2016-04-17 35 views
1

欲基本上轉OCaml中的基質結合列表的列(不使用遞歸或任何種類循環的)OCaml中

例如,如果我有以下矩陣:[[1;2];[3;4]]
我想有[[1;3];[2;4]]的輸出。

我做了什麼至今打破了原有的矩陣爲單獨列:

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

我把這個輔助函數從另一個功能:

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

我想這會結合所有的按我想要的方式列,但結果是輸出如下:[[1];[2];[3];[4]]

回答

0

我懷疑你的separate函數是否將矩陣分隔成列。這是我看到:

# let separate li = List.map (fun x -> [x]) li;; 
val separate : 'a list -> 'a list list = <fun> 
# List.map separate [[1;2];[3;4]];; 
- : int list list list = [[[1]; [2]]; [[3]; [4]]] 

我沒有看到列,我只是看到你已經把每個元素到它自己的名單。如果您使用List.tl而不是List.hd你的行中餘下的

# List.map List.hd [[1;2]; [3;4]];; 
- : int list = [1; 3] 

爲了讓你可以試試這個第一列。也許你可以使用摺疊來反覆應用並收集結果。

0

假設你的列表的列表是矩形的,this Standard ML code轉化爲OCaml的這樣:

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)。

仍然存在於此函數中的顯式遞歸不容易被映射/摺疊所取代,因爲這些函數一次只能處理一行,其中遞歸方案一次解決所有行的一部分(一部分)。你可能有更多的運氣與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矩陣的列:

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