当给出的列表不为空时,F#与空列表匹配

时间:2015-09-23 16:23:41

标签: f# pattern-matching

我试图找到矩阵的转置,我知道到目前为止我的代码不正确但我更关心的是为什么当我用它测试它时 转置[[4;3];[1;5];[6;7]]它会转到第一个匹配案例,这是一个空列表吗?

let rec transpose = function
     | [] -> failwith "Error, no matrix supplied"
     | [[]] -> []
     | [[x]] -> [[x]]
     | x::xs -> let temp = List.head x :: (List.map (fun n -> List.headn) xs)    
                temp :: transpose(xs);;

2 个答案:

答案 0 :(得分:5)

案例2:

[[]]

将匹配包含空列表的列表。

案例3:

[[x]]

将匹配包含包含单个项目的列表的列表。

这种情况:

x::xs

x进行一些处理,然后对xs进行递归,因此在transpose上调用[[4;3];[1;5];[6;7]]将导致使用以下参数对transpose进行递归调用:

[[4;3];[1;5];[6;7]]
[[1;5];[6;7]]
[[6;7]]
[]

您可以看到这些值都不匹配案例2或案例3,最终值与案例1匹配,因此递归最终将终止于案例1。

答案 1 :(得分:2)

找到矩阵转置的一个选项:

let transpose (matrix: 'a list list) = 
    let rec loop x number count = 
        if number < count then
            loop (List.foldBack(fun x acc -> (List.nth x number)::acc) matrix []::x) (number + 1) count
        else x
    if matrix.IsEmpty then []
    else loop [] 0 matrix.Head.Length |> List.rev


[[4;3];[1;5];[6;7]] |> transpose |> printfn "%A"
[[4;3;2];[1;5;0];[6;7;9];[4;3;2];[1;5;0]] |> transpose |> printfn "%A"
[] |> transpose |> printfn "%A"

打印:

[[4; 1; 6]; [3; 5; 7]]
[[4; 1; 6; 4; 1]; [3; 5; 7; 3; 5]; [2; 0; 9; 2; 0]]
[]

链接:

https://dotnetfiddle.net/095DRq