当前位置: 代码迷 >> 综合 >> Haskell 程序的 C 语言仿真——浅谈函数式编程的本质
  详细解决方案

Haskell 程序的 C 语言仿真——浅谈函数式编程的本质

热度:0   发布时间:2023-12-12 16:21:47.0

很多人认为,C 语言中只要不用变量,那就是函数式编程。其实,非也。这里展示一下,C 语言到底怎样写,才算是“函数式编程”。希望通过这些例子,加深对函数式编程本质的理解。

如何理解 Haskell 无变量、函数是第一类对象这样一个说法?

我们先来看一段 Haskell 代码。

a = 1
b = 2
c = a + b

那么,等价的 C 语言代码是下面这个样子吗?

int a = 1
int b = 2
int c = a + b

非也,确切一点,应该是下面这个样子:

int a() { return 1;}
int b() { return 2;}
int c() { return a() + b();}

在 Haskell 中,a = 1 就是无自变量的常数函数。函数 a 的类型大概是下面这个形式:

a :: Integer

所谓 a 的值无法改变,其实是指函数 int a() { return 1;} 的返回值无法改变。函数是 Haskell 的基本元素,地位和 C 语言的变量一样。这注定了 Haskell 语言和 C 语言设计思想的根本不同。

更复杂一点的例子

求自然数的前 n 项和, Haskell 代码如下:

sumn 0 = 0
sumn n = n + sumn (n - 1)

改写成等价的 C 语言代码:

int sumn(int n) {if (n == 0) return 0;return n + summn(n - 1);
}

貌似没问题,但是,int n 这种声明按照函数式编程思想应该写成 int n() 这种形式,那么正确的写法应该下面这样:

int sumn(int n()) {if (n() == 0) return 0;return n() + summn(n() - 1);
}

冲突出现了, 调用 sumn 100 时,Haskell 会自动在堆栈中生成临时函数 n = 100,在 C 语言中,这一点做不到。原因很简单,我们看看 n 和 100 在 Haskell 语言中的类型声明:

>> n=100
>> :type n
n :: Num p => p
>> :type 100
100 :: Num p => p

在这个例子中, n 和 100 的类型都是 Num p => p,翻译成 C 语言的声明,n 和 100 都是 int F() 类型的函数。C 语言的机制和 Haskell 完全不一样,不可能模仿出 Haskell 的编程风格。

Haskell 语言把 C 语言中的变量和函数抽象成了同一种形式,变量声明和函数声明的语法是完全一样的,因此语言内涵的抽象和精炼,使得 Haskell 语言的表达能力更为强大。C 和 Haskell 区别不仅仅在于是否运用变量的问题,C语言即使废除了变量,也成不了 Haskell。二者的根本出发点是不一样的,C 就是为CPU直接服务的,编程模型基于CPU工作模型建立,基本操作是把数据在内存里面不断倒腾,适合为基于冯诺依曼架构的计算机开发底层硬件相关的实时性要求高的软件。Haskell 是面向数学模型的,适合从高度抽象的层面解决问题,基本操作是定义数据之间的函数关系,更适合开发应用系统。

  相关解决方案