使用模式匹配F#重写代码

时间:2017-10-31 11:39:00

标签: f#

嗨,我对F#和编程都很新。我现在正在努力学习它,并已注册了一门课程,但我似乎仍然没有得到它。请帮助。我试图重写以下代码:

let rec msort xs =
    let sz = List.length xs
    if sz < 2 then xs  
    else let n = sz / 2
        let ys = xs. [0..n-1]
        let zs = xs.[n..sz-1]
        in merge (msort ys) (msort zs)

//************ Utility-funktion merge

let rec merge xs ys =   if List.isEmpty xs then ys   else if
List.isEmpty ys then xs   else let x = List.head xs
        let y = List.head ys
        let xs = List.tail xs
        let ys = List.tail ys
        in if x < y then x :: merge xs (y::ys)
                else y :: merge (x::xs) ys  </i>

我的解决方案 - 哪个不起作用:

let rec msort xs =
  let sz = List.length xs
    match sz with
    | sz < 2 -> xs
    |_ -> n = sz/2
          let ys = xs. [0..n-1]
          let zs = xs.[n..sz-1]
          in merge (msort ys) (msort zs)    


//************ Utility-funktinen merge

let rec merge xs ys =   match xs with   |[] -> [ys]
    match ys with
      |[] -> [xs]   |_ ->
        let x = List.head xs
        let y = List.head ys
        let xs = List.tail xs
        let ys = List.tail ys if x < y then x :: merge xs (y::ys)
                                  |_ ->
                                        y :: merge (x::xs) y

1 个答案:

答案 0 :(得分:6)

请注意,您可以通过在元组中编写它们来匹配两个值,而不是使用绑定列表头部和尾部,您可以在&#39;形状上使用模式匹配。直接在守卫中的列表,虽然它用于整个列表的相同名称以及后来用于尾部的事实有点不幸,因为它可能导致混淆,但它工作正常,因为F#遮蔽了值:

let rec merge xs ys = 
    match (xs, ys) with 
    | [], _ -> ys
    | _, [] -> xs
    | x::xs, y::ys -> 
        if x < y then x :: merge xs (y::ys)
        else y :: merge (x::xs) ys

let rec msort xs = 
    let sz = List.length xs 
    match sz with 
    | sz when sz < 2 -> xs 
    |_ -> 
        let n = sz/2 
        let ys = xs. [0..n-1] 
        let zs = xs.[n..sz-1]
        merge (msort ys) (msort zs)

你在卫兵的条件下错过了关键字when。 我还修改了原始代码中的一些小细节。