F# 函数式编程之 - 前所未见的 unit 类型

Author: 102419@gmail.com
Created at: 2020-12-01

现在的主流编程模式是命令式(imperative), 例如 Java, C, Python 等大多数常见的语言都属于这类。

命令式编程的函数可以没有返回值,比如(以 javascript 为例):


    function ok() {
      console.log('ok')
    }
    

上面这个函数就没有返回值。

但函数式编程则不一样,名符其实,就是由数学里的 “函数” 概念为基础的。

在数学里,“函数” 表示一种映射关系,比如(以下是 F# 代码):


    let intToString x = sprintf "%i" x
    

上面这个函数的输入整数,输出字符,其映射关系记作 int -> string

那么,如果将本文开头那里的 javascript 改成 F# 呢?


    let ok () = printf "ok"
    

上面这个函数,是不是和 JavaScript 一个没有输入,也没有输出?不是的。

它输入 unit, 输出也是 unit,其映射关系记作 unit -> unit

unit 是一个类型(就像 int 或 string), 而 unit 类型只有一个值 (), 很神奇, () 不是表示没有参数的括号,它其实是参数本身,就是一个值,就像 1, 2, 3 或 "abc" 一样的值。

请看上面的代码,在第一个 ok 后面的括号,就是类型为 unit 的值 (),由于 F# 可以省略括号,所以它看起来像一对括号。

我们可以把括号补充上:


    let ok (()) = printf "ok"
    

上面的代码,外层的是括号,里面的却是类型为 unit 的值 ()

再看看下面这个,javascript 如果再加一层括号就不行了:


    function ok(()) {
      console.log('ok')
    }
    

上面的 javasript 代码,双层括号,会报错 SyntaxError。

综上所述,javasript 里没有 () 这种值,而在 F# 里 () 是一个实在的值。

本文介绍了 F# 里(同时也是函数式编程里)的一种特殊类型 unit 及其值 (), 虽然并没有什么了不起的作用,但在主流命令式编程中没有这个概念,有点新奇,同时也体现了在函数式编程里,函数严格遵守着映射关系。

←← →→