避免F#中的代码重复

Joh*_*han 11 f# tail-recursion code-duplication

我有两个代码片段,试图将浮动列表转换为Vector3或Vector2列表.这个想法是从列表中一次取2/3个元素并将它们组合成一个向量.最终结果是一系列向量.

    let rec vec3Seq floatList =
        seq {
            match floatList with
            | x::y::z::tail -> yield Vector3(x,y,z)
                               yield! vec3Seq tail
            | [] -> ()
            | _ -> failwith "float array not multiple of 3?"
            }

    let rec vec2Seq floatList =
        seq {
            match floatList with
            | x::y::tail -> yield Vector2(x,y)
                            yield! vec2Seq tail
            | [] -> ()
            | _ -> failwith "float array not multiple of 2?"
            }
Run Code Online (Sandbox Code Playgroud)

代码看起来很相似,但似乎无法提取公共部分.有任何想法吗?

kvb*_*kvb 13

这是一种方法.我不确定它到底有多简单,但它确实抽出了一些重复的逻辑.

let rec mkSeq (|P|_|) x =
  seq {
    match x with
    | P(p,tail) -> 
        yield p
        yield! mkSeq (|P|_|) tail
    | [] -> ()
    | _ -> failwith "List length mismatch" }

let vec3Seq =
  mkSeq (function
  | x::y::z::tail -> Some(Vector3(x,y,z), tail)
  | _ -> None)
Run Code Online (Sandbox Code Playgroud)

  • 我看的越多,我就越喜欢它. (3认同)
  • 很美丽. (3认同)
  • 很好地使用了部分活动模式. (3认同)