haskell - 无点代码更有效,还是更简洁?

标签 haskell coding-style refactoring pointfree

我编写了以下代码,它采用了一堆点并使用光泽库将它们绘制在屏幕上。

let s = blocks pes
    pts = map (map mkPt) s  {- stitches to points-}
    lines = map Line pts    {-points to lines -}
    pict = Pictures lines   {- lines to a picture -}
  in do  displayInWindow "My Window" (200, 200) (10, 10) white pict

它工作得很好,但我突然想到有一个重复的模式:一系列函数调用,每个函数调用的结果都输入下一个参数的最后一个参数。
因此,我通过删除中间变量、颠倒顺序并使用函数组合(“。”)链接函数进行重构,如下所示:
let pict = Pictures . (map Line) . (map $ map $ mkPt) . blocks $ pes
                in do  displayInWindow "My Window" (200, 200) (10, 10) white pict

令人高兴的是,这也很好用。但我想知道我是否在强调可读性,或者我只是不习惯阅读和编写无点样式代码。另外,我如何推断这段代码?第二个版本更高效,还是更简洁?我可以在风格上做些什么来使它更清晰吗?

最佳答案

一些快速的建议:

let pict = Pictures . (map Line) . (map $ map $ mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict

你有一些多余的东西可以直接删除:
let pict = Pictures . map Line . (map $ map mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict

无论如何,map (map mkPt) 并没有避免括号。术语,所以去掉 $ :
let pict = Pictures . map Line . map (map mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict

为了清楚起见,您可以在多行上编写组合链:
let pict = Pictures 
         . map Line 
         . map (map mkPt) 
         . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict
do block 是多余的,因为它只有一个语句,您可以将最终应用程序移到定义之外:
let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white
                . Pictures 
                . map Line 
                . map (map mkPt) 
                . blocks
in displayPict pes

可以合并两个map年代:
let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white
                . Pictures 
                . map (Line . map mkPt) 
                . blocks
in displayPict pes

有时,对于长链来说,使用 Control.Arrow 中的反向组合运算符也更具可读性。 :
let displayPict = blocks
                  >>> map (Line . map mkPt) 
                  >>> Pictures
                  >>> displayInWindow "My Window" (200, 200) (10, 10) white
in displayPict pes

但所有这些都是可选的;给你的代码调味。

关于效率,我认为没有理由认为这两者会有所不同,一旦 GHC 的优化器完成了代码。

关于haskell - 无点代码更有效,还是更简洁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6494443/

相关文章:

language-agnostic - 'foo' 的真正含义是什么?

user-interface - 在 MVP 界面模式中划分已经变得太大的演示者的好做法是什么?

class - 你如何重构一个上帝类?

parsing - 如何在 Haskell 中组合解析器最多 n 次?

performance - 处理海量数据

haskell - 使用haskell的单例,如何编写 `fromList::[a] -> Vec a n` ?

java - 如何重构使用 "Strategies"的大类?

haskell - 纯函数式语言(haskell)用户如何进行设计?他们使用什么替代 uml?

javascript - 用于标记私有(private)成员的前导下划线

python - 在Python中使用@property构建一个类