【发布时间】:2019-12-23 20:20:45
【问题描述】:
在阅读Chapter 4 from Real World Haskell 时,我用以下几行解决了第 97 页的练习 1
asInt :: String -> Int
asInt ('-':x) = asInt x
asInt xs = foldl (\a x -> a*10 + digitToInt x) 0 xs
然后我从链接页面检查了一些cmets,并验证了这是大多数人采用的解决方案。
另一方面,我认为最好不要将函数编写为 lambda (\a x -> a*10 + digitToInt x),因为它非常冗长,并且会为参数(a 和 x)命名,而实际上不需要给定一个,但作为其他函数的“组合”,即二元函数(*)、(+)和一元函数digitToInt;但是我不知道如何将这三个组合成一个与上面的 lambda 等效的二进制函数。
我认为构成的成分是(*10),必须作用于foldl 的累加器的一元函数digitToInt,作用于列表元素xs 的一元函数,以及@ 987654334@,那得把这两者结合起来。
【问题讨论】:
-
见pointfree.io应该是
(.digitToInt).(+).(*10) -
Pointfree 代码通常是“仅仅因为你可以并不意味着你应该”的情况。当您拥有一长串具有明显输入-输出管道的函数时,它最有用。但是,当您开始使用
(.)运算符将内容放在正确的位置时,请记住,变量名的发明是有原因的。 -
@FrownyFrog,感谢您让我知道这个 Pointfree.io 网站!但是,如果您可以编写自己的答案来解释该函数组合的工作原理,那就太好了。
-
\a x -> a*10 + digitToInt x不需要解释,但(.digitToInt).(+).(*10)需要解释这一事实是关于使用哪个代码的大量提示。无点风格在很多情况下可以非常漂亮,但在其他情况下它很快退化为混淆,不愧为无点风格。区分两者对于生成高质量的代码非常重要。 -
我明白你的意思,@chi;但是,我仍然渴望了解在这种情况下无意义风格的功能是如何工作的;不一定是因为我会使用它,因为我不能否认它混淆了函数的含义(至少在这种情况下),而是因为我认为我可以从中学到一些东西,而 lambda 只能教语法。
标签: haskell lambda functional-programming pointfree