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

F#当给定的列表不为空时与空列表匹配,f#,pattern-matching,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

我试图找到矩阵的转置,我知道我的代码到目前为止是不正确的,但我更关心的是为什么我用 转置
[[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:

[[]]
将匹配包含空列表的列表

案例3:

[[x]]
将匹配包含单个项目的列表

本案:

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

[[4;3];[1;5];[6;7]]
[[1;5];[6;7]]
[[6;7]]
[]
您可以看到,这些值都与案例2或案例3不匹配,而最终值与案例1匹配,因此递归最终将在案例1终止。

案例2:

[[]]
将匹配包含空列表的列表

案例3:

[[x]]
将匹配包含单个项目的列表

本案:

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

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

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

查找矩阵转置的选项之一:

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"
链接:


查找矩阵转置的选项之一:

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"
链接:


它不是直接这样做的,它是通过最后一个案例结尾处的递归调用来实现的。当然,一旦
x::xs
案例递归地到达结尾处,它就会到达那里。它不是直接这样做的,它是通过上一个案例结尾处的递归调用实现的。当然,一旦
x::xs
案例递归地到达结尾,它就会到达那里。谢谢,这让我现在非常清楚地理解了它!还有一个问题,如果我用转置[]测试它,我会得到一个值限制错误…为什么会发生这种情况?“如何修复”部分是:使用
列表。空的
代替
[]
应该会有帮助。至于“为什么”部分——试着去寻找一个最好的解释。谢谢,这让我现在明白了!还有一个问题,如果我用转置[]测试它,我会得到一个值限制错误…为什么会发生这种情况?“如何修复”部分是:使用
列表。空的
代替
[]
应该会有帮助。至于“为什么”部分,试着去寻找一个最好的解释。