Scala中的真实世界函数式编程
SOOOO ...
半群,幺半群,单子,函子,镜头,变形,变形,箭......这些都听起来不错,经过一两次(或十次)练习后,你就能掌握它们的本质。 和Scalaz
,你可以免费获得它们......
然而,就现实世界的编程而言,我发现自己很难找到这些概念的用法。 是的,当然,我总是在网上找到一些人使用Monads for IO或者在Scala中使用镜头,但是......仍然...
我试图找到的是沿着模式的“规定性”路线的东西。 就像这样:“在这里,你正试图解决这个问题,解决这个问题的一个好方法就是通过这种方式使用镜头!”
建议?
更新:按照这些原则,有一两本书会很棒(感谢Paul):Java核心库中的GoF设计模式示例
我在9月份重新讨论了通过scalaz.Validation的monoids和applicative functors / monads的实际应用。 我在Scala Lift Off上发表了另一个版本的讲座,其中重点更多地放在了验证上。 我会观看第一次谈话,直到我开始验证,然后跳到第二次谈话(27分钟)。
还有一个我写的要点,它显示了如何在“实用”应用程序中使用验证。 也就是说,如果你正在设计夜总会保镖软件。
函数式编程的关键是抽象和抽象的可组合性。 Monads,Arrows,Lenses,这些都是已被证明是有用的抽象,主要是因为它们是可组合的。 你已经要求一个“规定性”的答案,但我要说不。 也许你不相信函数式编程很重要?
我相信很多StackOverflow的人会乐意尝试并帮助您解决FP方式的特定问题。 有一个东西的列表,你想遍历列表并建立一些结果? 使用折叠。 想要解析XML? hxt使用箭头。 还有monads? 好吧,大量的数据类型是Monads,所以了解它们,你会发现你可以操纵这些数据类型的很多方法。 但它的一种很难仅仅凭空举例并说“镜头是正确的方式来做到这一点”,“monoids是最好的方式来做到这一点”,等等。你如何向新手解释什么是使用for循环是? 如果你想[空白],然后使用for循环[以这种方式]。 这是如此普遍; 有很多方法可以使用for循环。 这些FP抽象也是一样。
如果你有多年的OOP经验,那么不要忘记你曾经是OOP的新手。 学习FP方法需要花费时间,并且有更多的时间去了解一些面向对象的倾向。 给它时间,你会发现功能性方法的很多用途。
我认为你可以采用相反的方法,而是在编写一小部分功能时,问问自己是否适用:半群,幺半群,单子,函子,透镜,变质,变形,箭头......很多这些概念可以以当地方式使用。
一旦你开始了这条路线,你可能会在任何地方看到使用。 对我而言,我得到了半群,Monoid,Monads,Functors。 因此,请回答这个问题的例子如何填充具有新值的对象列表。 对于提问的人来说这是一个真正的用法(一个自我描述的小白鼠)。 我试图用简单的方式来回答,但我必须克制自己不要搔痒,“这里有怪癖”。
现在抓住它:使用foldMap
和Int和List是foldMap
并且在处理元组,地图和选项时保留monoid属性:
// using scalaz
listVar.sliding(2).toList.foldMap{
case List(prev, i) => Some(Map(i -> (1, Some(List(math.abs(i - prev))))))
case List(i) => Some(Map(i -> (1, None)))
case _ => None
}.map(_.mapValues{ case (count, gaps) => (count, gaps.map(_.min)) })
但我不认为我会使用硬核功能编程来达到这个结果。 它更自然地通过认为这看起来更简单,如果我将这些monoids组合起来,以及scalaz具有像foldMap
这样的实用方法。 有趣的是,当查看结果代码时,我完全用monoid来思考并不明显。