如何在Haskell中进行多次eta减少

dit*_*lav 6 haskell

我有一个任务是从[[a]]矩阵中获取一列.

一个简单的解决方案就是

colFields :: Int -> [[a]] -> [a]
colFields n c = map (!! n) c
Run Code Online (Sandbox Code Playgroud)

当减少一个抽象级别时,它将是

colFields n = map (!! n)
Run Code Online (Sandbox Code Playgroud)

我觉得我可以n轻易摆脱,但我做不到.

bhe*_*ilr 13

你在寻找什么

colFields = map . flip (!!)
Run Code Online (Sandbox Code Playgroud)

但是,这不是很清楚,我会把n参数留在那里.使用n作为显式参数,我立即理解该函数的作用.没有它,我必须考虑一下才能理解定义,即使对于这样的简单情况也是如此.

我通过使用pointfree工具非常简单地获得了这个答案,尽管有方法可以手动推导出这个.

  • 这里有点紧张......`flip(!!):: Int - > [a] - > a`从部分应用程序的角度看比`(!!)`更自然的函数,其中参数顺序用于表示法目的.也许我会称它为"索引".在那种情况下`地图.index`很好.但我同意`地图.翻转(!!)`有点令人费解,无法按原样阅读. (3认同)
  • 我同意这不是非常清楚,有点版本更可取.我手动弄清楚了; 这是我的思路:"我希望我安装了`pointfree`.`(!!):: [a] - > Int - > a`.如果我把'Int`作为第一个参数我可以编写它用`(.)`.这就是'翻转'的用途.让我们问`ghci`:`:t flip(!!)`;`:t map.翻转(!!)`.那看起来不错.哦,darn, @bheklilr打败了我." (2认同)
  • @ChristianConkle为了公平起见,我只需将代码复制/粘贴到我已经打开的GHCi中,并将`:pf`设置为调用`pointfree`工具.一旦我看到建议的缩减,我就会想"哦,是的,你必须在`(!!)`上使用'flip`来首先使用`n`,然后使用`将结果传递给`map`( .)`.我_understand_无点版本,但它不是没有少量的努力.有点版本对我来说很明显(也许我写了太多Haskell ......) (2认同)