8

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

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

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

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

4

5 回答 5

14

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

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

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

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

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

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

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

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

    可以替换为:

    foo map ( _ + 2 )
    
于 2013-05-07T13:28:24.497 回答
11

我敢说您的目标已经具有误导性:

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

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

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

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

于 2013-05-07T12:33:48.447 回答
8

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

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

函数式编程

介绍

功能性思维

斯卡拉

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

于 2013-05-07T12:35:53.203 回答
2

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

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

于 2013-05-07T13:06:10.467 回答
1

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

这已经是一个好的开始,要避免的其他非功能性的事情是可变集合和循环。

看看不可变集合和递归。

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

于 2013-05-07T12:45:31.533 回答