【问题标题】:How to enforce Functional Programming on Scala如何在 Scala 上执行函数式编程
【发布时间】:2019-12-26 19:31:38
【问题描述】:

我开始学习函数式编程,并希望使用 Scala,而不是 Haskell 或 Lisp。

但有些人声称,将 Scala 作为第一种函数式语言学习会减慢您学习函数式编程的速度,因为 Scala 允许您以两种方式进行编程,并且在遇到难题时倾向于以过程方式进行编程。

我如何确保以纯粹的功能方式进行编程?也许,由于无法正确区分这两种样式,我会不小心按程序进行编程)。

例如,我知道我应该只使用 vals 而不是 vars。

【问题讨论】:

标签: scala


【解决方案1】:

其他答案已经提出了一些很好的观点,但是为了尝试快速了解一些指导方针,我将如何开始:

首先,要完全避免的一些事情:

  • 不要使用var 关键字。
  • 不要使用 while 关键字。
  • 不要使用 scala.collection.mutable 包中的任何内容。
  • 不要使用asInstanceOf 方法。
  • 不要使用null。如果您遇到过null(在别人的代码中),请立即将其包装成更合适的数据类型(通常Option 会很好)。

然后,通常要避免几件事:

  • 小心调用返回类型为Unit 的任何内容。返回类型为Unit 的函数要么什么都不做,要么只是通过副作用起作用。在某些情况下,您将无法避免这种情况(IO 是显而易见的),但如果您在其他地方看到它,则可能是杂质的迹象。
  • 小心调用 Java 库 - 它们通常在设计时没有考虑到函数式编程,并且通常会要求您放弃函数式方法。

一旦你避免了这些事情,你可以做些什么来让你的代码更实用?

  • 当您执行直接递归时,寻找机会通过使用高阶组合器来概括它。 fold 可能是您最大的候选对象 - 列表上的大多数操作都可以通过合适的 fold 来实现。
  • 当您看到对数据结构的解构操作(通常通过模式匹配)时,请考虑是否可以将计算提升到结构中并避免对其进行解构。一个明显的例子是下面的代码sn-p:

    foo match {
      case Some(x) => Some(x + 2)
      case None => None
    }
    

    可以替换为:

    foo map ( _ + 2 )
    

【讨论】:

  • null 包装到选项可能会导致货物崇拜。我认为您不必盲目遵循此规则:有时代码会因使用 local 选项而有些混乱,而使用 if 就足够了。
  • 这是一个公平的观点。一般来说,我不一定会推荐它,但对于作者的具体情况 - 确保他们以纯粹的功能方式编写 - 我会说从他们拥有的东西中完全删除 null 是一种合理的方法处理。
【解决方案2】:

我敢说你的目标已经误导了:

我开始学习函数式编程,我真的很想学习 Scala,而不是 Haskell 或 Lisp。

如果您真的对学习函数编程的概念感兴趣,那么为什么不使用像 Haskell 这样(或多或少)不允许您使用过程或面向对象概念的语言呢?最后,该语言“只是”一种帮助您学习 FP 概念的工具,您也可以阅读大量有关 FP 的论文。至少在理论上,我认为使用手头的具体工具学习计算机科学概念通常更容易。

另一方面,如果您有兴趣学习 语言 Scala,那么为什么不使用它提供的所有功能,无论它们来自 FP 还是 OO 世界? p>

为了总结一个实用的建议:您可以搜索使用 Scala 的 FP 教程或描述如何在 Scala 中实现某些 FP 概念的博客文章等,并尝试遵循它们。这样,您就不太可能使用非 FP 概念。

【讨论】:

    【解决方案3】:

    您购买法拉利并不是为了运送家具。 Scala 的基本优势在于,用您的话来说,它是双向的:)。是否使用函数式编程取决于您使用的技术。

    您能做的最好的事情是彻底复习函数式编程的基本概念,并寻求相应概念的适当 Scala 实现。但是,如果您想编写纯函数式编程,那么请使用 Haskell、Lisp、Erlang、OCaml 或任何其他纯函数式方言。

    函数式编程

    Introduction

    Functional thinking

    斯卡拉

    如果您想学习 Scala,请确保在您的学习曲线中同时包含 OO 和 FP。恕我直言,地球上最先进的编译器使 Lambda 表达式 + OO 概念 + 语法糖成为可能,这导致了一些非常惊人的事情。好好利用吧!

    【讨论】:

    • 我会说大多数 Lisps 和 Erlang 都不是纯函数式的。
    • 你买法拉利不是为了送家具。
    【解决方案4】:

    我认为学习是非线性过程,它有助于看到做同一件事的许多方法,也可以投机取巧并使用任何可用的学习资源。例如,Scala 的创建者 Martin Odersky 提供了一个名为“Scala 中的函数式编程原理”的免费课程https://class.coursera.org/progfun-002/class/index 有一些非常高质量的视频讲座,还有一些非常好的作业,自动评分器会告诉你你的代码没有功能够了,因为你使用的是var 而不是val,所以你失去了风格点

    我认为您要关注的是学习函数式编程范式,对我而言,学习范式就是了解哪些类型的问题在一个范式中易于解决,而在另一种范式中难以解决。专注于范式,我想你会发现同时学习 Haskell 和 Scala 会更快地教你函数范式,因为你将能够问问题 Scala 和 Haskell 之间有哪些共同特征,有什么区别.. ..等

    【讨论】:

      【解决方案5】:

      I know, for example, that I should only use vals and not vars.

      这已经是一个好的开始,其他不那么实用的东西是可变集合和循环。

      看看不可变集合和递归。

      当然,一旦您熟悉了函数式概念,也可能有充分的理由使用 scala 的非函数式特性。

      【讨论】:

        猜你喜欢
        • 2020-12-31
        • 2013-08-12
        • 2016-05-12
        • 2011-05-07
        • 1970-01-01
        • 1970-01-01
        • 2015-10-03
        • 2017-04-16
        • 1970-01-01
        相关资源
        最近更新 更多