【问题标题】:Functional Programming and Type Systems函数式编程和类型系统
【发布时间】:2010-07-01 19:40:33
【问题描述】:

一段时间以来,我一直在学习各种函数式语言,包括 Haskell、Scala 和 Clojure。 Haskell 有一个非常严格且定义良好的静态类型系统。 Scala 也是静态类型的。另一方面,Clojure 是动态类型的。

所以我的问题是

  1. 类型系统在函数式语言中扮演什么角色?
  2. 一种语言是否必须具有类型系统才能使其正常工作?
  3. 一种语言的“功能”级别与该语言的类型系统的种类有什么关系?

【问题讨论】:

    标签: clojure functional-programming programming-languages type-systems


    【解决方案1】:

    一种语言不需要类型化才能成为函数式 - 函数式编程的核心是 lambda calculus,它有无类型和 typed 两种变体。

    类型系统扮演两个角色:

    • 它在编译时保证在运行时不会发生一类错误。错误类别通常包括尝试将两个字符串相加,或尝试将整数作为函数应用。
    • 它有一些效率优势,因为对象在运行时不需要携带它们的类型,因为类型已经在编译时建立。这被称为type erasure

    在像 Haskell 这样的高级类型系统中,类型系统可以提供更多好处:

    • 重载:使用一个标识符来引用不同类型的操作
    • 它允许库根据使用的类型自动选择优化的实现(使用Type Families
    • 它允许在编译时证明强大的不变量,例如红黑树中的不变量(使用Generalised Algebraic Datatypes

    【讨论】:

    • 不过,这些高级特性并不局限于函数式语言。
    • @sepp2k 是的 - 你能想到一个类型系统特性本质上仅限于函数式语言吗?
    • 没有。这就是为什么我不会说“语言的功能级别”和类型系统之间有很大的关系。
    • 可以在不使用 lambda 演算的情况下制作函数式语言。事实上,以二元布尔函数 NAND 作为其唯一操作的语言是图灵完备的。 NAND 对我来说看起来非常透明。
    • @Lajla:取决于你对“功能”的定义。
    【解决方案2】:

    类型系统在函数式语言中扮演什么角色?

    对于 Simon Marlow 的出色回答,我要补充一点,类型系统,尤其是包含代数数据类型的类型系统,可以更轻松地编写程序:

    • 在面向对象语言中有时使用 UML 图表示的软件设计使用类型非常清楚地表示。这种清晰性尤其体现在不仅具有类型,而且模块也具有类型时,例如在Objective Caml或Standard ML中。

    • 当一个人在编写代码时,一些简单的启发式方法可以非常非常容易地根据类型编写纯函数:

      • 函数类型的值始终可以使用 lambda 创建。
      • 函数类型的值始终可以通过应用来使用。
      • 可以通过应用任何类型的构造函数来创建代数数据类型的值。
      • 可以通过使用case 表达式检查代数数据类型的值来使用它。

      根据这些观察结果,以及一个简单的规则,除非有充分的理由,否则函数应该使用它的每个参数,因此很容易减少可以编写给极少数候选者的可能代码的空间.例如,没有那么多合理的类型函数(使用 Haskell 表示法)

      forall a . (a -> Bool) -> [a] -> Bool
      

      使用类型来创建代码的艺术被称为类型导向编程。当它运作良好时,你会听到函数式程序员说类似 “一旦我们得到正确的类型,代码实际上是自己写的。” 因为类型通常比 代码,这是一个很大的胜利。

    【讨论】:

      【解决方案3】:
      1. 与任何编程语言相同:它可以帮助您避免/发现代码中的错误。在静态类型的情况下,一个好的类型系统可以防止编译带有某些类型错误的程序。
      2. 没有。 untyped lambda calculus 是函数式编程语言的原型,顾名思义,它是完全无类型的。
      3. 在函数式语言(以及可以将函数用作值的任何其他语言)中,类型系统需要知道函数的类型。除此之外,函数式语言的类型系统没有什么特别之处。

        在纯函数式语言中,您需要抽象副作用,因此您希望类型系统能够以某种方式支持它。例如,如果您想拥有像 Clean 中这样的世界类型,您会希望类型系统支持唯一性类型以确保正确使用。

        如果你想有一个像 haskell 中的 IO monad,你需要一个 IO 类型(尽管像 haskell 中的 monad 类型类不需要有一个 IO monad,所以你不需要一个类型系统,它支持)。

      【讨论】:

      • 你的意思是静态或动态类型的语言在“功能”级别之间没有区别吗?
      • @abhin4v:我注意到你所说的“功能级别”是什么意思
      【解决方案4】:

      1:与其他任何操作一样,它会阻止您执行不明确的操作,或者其结果对人类来说是“荒谬的”。就像对整数进行浮点加法一样。
      2:不,世界上最古老的编程语言(无类型的)lambda 演算既是函数式的又是无类型的。
      3:几乎没有,功能只是意味着没有副作用、没有突变、引用透明等等。

      请记住,最古老的函数式语言,无类型 lambda 演算没有类型系统。

      【讨论】:

        猜你喜欢
        • 2013-04-03
        • 1970-01-01
        • 2012-06-29
        • 2013-05-19
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2016-11-19
        • 2020-10-26
        相关资源
        最近更新 更多