有没有办法“打开Seq”或类似的效果?

时间:2016-02-24 17:26:00

标签: f# refactoring

a 
|>Seq.map fixLine 
|>Seq.map splitCells 
|>Seq.map getName 
|>Seq.where(fun a->not<|Seq.isEmpty a) 
|>Seq.map fixName

在保持大量Seq时总是觉得很烦人。在线。建议省略它们的好方法......

例如,对列表使用List.map,对seq使用map,或者在使用seq和list时将它们拆分为不同的模块。

a
|>map fixLine
|>map splitCells
|>map getName
|>where(fun a->not<|isEmpty a)
|>map fixName

看起来真的好多了。

2 个答案:

答案 0 :(得分:6)

您也可以为所需的函数定义别名:

let map = Seq.map
let where = Seq.filter

或者你可以通过定义自己的运算符来使它变得更加简洁:

let (|!>) s f = Seq.map f s
let (|*>) s f = Seq.filter f s

a
|!> fixLine
|!> splitCells
|!> getName
|*> (fun a->not<|isEmpty a)
|!> fixName

但是在这一点上,你的代码变得过于神秘 - 即,看到代码的人将很难理解正在发生的事情。

最后,通过注意map s的合成是map的合成,您可以使原始代码看起来更好一些:

a
|> Seq.map (fixLine >> splitCells >> getName)
|> Seq.filter (not << isEmpty)
|> Seq.map fixName

这是我个人更喜欢的解决方案。

总的来说,我的个人经验表明,尽管通过使重复部分本身变小来“修复”重复性的第一个冲动,但通常是一个更好的解决方案,不仅会使您的代码看起来更好,但也有更好的因素。

答案 1 :(得分:4)

我认为没有一种简单的方法可以避免重复Seq - 这只是F#让事情变得更加明确的一个地方(这样你就知道发生了什么)。

但是你可以使用F# Core Fluent library,它为.提供了更像C#的语法:

a.map(fixLine).map(splitCells).map(getName).filter(isEmpty >> not).map(fixName)