2012-03-02 116 views
0

是否有意义有这样的功能定义从挤压元组(A,(B,C))至(A,B,C)中fsharp

let squash12 (e:('a*('b*'c) )) = e |> (fun (a,(b,c) ) -> (a,b,c )) 
let squash21 (e:(('a*'b)*'c )) = e |> (fun ((a,b),c ) -> (a,b,c )) 
let squash13 (e:('a*('b*'c*'d))) = e |> (fun (a,(b,c,d)) -> (a,b,c,d)) 

let seqsquash12 (sa:seq<'T>) = sa |> Seq.map squash12 
let seqsquash21 (sa:seq<'T>) = sa |> Seq.map squash21 
let seqsquash13 (sa:seq<'T>) = sa |> Seq.map squash13 

我找不到另一种方法,使我核心代码递归(导致嵌套元组),但暴露映射到广义n维坐标的简单函数。

回答

2

我会标明你的函数为内联,使他们可能只是

let inline squash1 (a,(b,c)) = (a,b,c) 

而且,你不需要lambda表达式(fun ...)

+0

THKS。我注意到类型推断很慢(我只使用基本函数的更高阶的东西),所以我不妨指定它的类型,如果它加快了速度。 – nicolas 2012-03-02 10:17:19

+0

@nicolas - 真的,我不认为类型推理很慢+这个版本在运行时会更快(避免函数调用) – 2012-03-02 10:21:07

+0

@nicolas:请参阅我的答案,以获得一般情况下的建议。 – pad 2012-03-02 10:25:49

2

是的,这样做是有道理的。该建议是避免拉姆达使这些功能更易于阅读:

let squash12 (a, (b, c)) = a, b, c 

如果遇到不同的元数内的元组,很多时候,他们转换成列表是不是一个坏主意。例如,e成为两个列表的元组:

(a, (b, c)) ~> ([a], [b; c]) 
(a, b), c) ~> ([a; b], [c]) 
(a, (b, c, d)) ~> (a, [b; c; d]) 

,我们只需要一个序列功能:

let seqsquash sa = sa |> Seq.map (@) 

问题是你失去对输入的大小控制。在列表模式匹配可以帮助:

let squash12 (xs, ys) = 
    match xs, ys with 
    | [a], [b; c] -> xs, ys 
    | _ -> failwith "Wrong input size" 
相关问题