热爱函数式的你,句句纯正的 Haskell【函数篇】

简介: Haskell 值与函数是统一的,函数只是需要其他参数输入的值。如果定义的是函数,那么这个函数的行为在运行过程中也是不会改变的,对于某一个特定的输入返回的结果总是确定的,这样的函数为纯函数。


函数本质



Haskell 里变量的值在绑定后不会改变,所有变量一定意义上可以理解为定值。

无论如何,定义过的值是没法再改变的。


Haskell 值与函数是统一的,函数只是需要其他参数输入的值。如果定义的是函数,那么这个函数的行为在运行过程中也是不会改变的,对于某一个特定的输入返回的结果总是确定的,这样的函数为纯函数。


有人觉得不改内存状态的想法听上去很荒诞,甚至觉得这样是没有办法做计算的。其实,这两种想法都是错误的。不改变内存状态自有道理,而其它编程语言可以完成的工作,Haskell 一样可以完成。


再三强调,在 Haskell 中,函数与值没有本质的区别,它可以是单一的定值,也可以是任意两个函数间的映射;


实际上,在 Haskell 世界里,所有的运算符号都可以被看做是函数,如加号 + 是一个需要两个参数的函数。


Prelude> (+)5 7
12


函数定义



直接上干货~

实现:f(x) = 4x+ 1


Prelude> f1(x)=4*x + 1
Prelude> f1 4
17
Prelude> :t f1
f1 :: Num a => a -> a


再比如实现:f(x,y) = 4x+ 5y+ 1,

我们可以设想到这个函数的类型是:


f2 :: Num a => (a, a) -> a


验证一下:


Prelude> f2(x,y)=4*x+5*y+1
Prelude> f2(4,3)
32
Prelude> :t f2
f2 :: Num a => (a, a) -> a


确实如此;b( ̄▽ ̄)d

Haskell 中定义的函数的大致格式是这样的:


// 定义方式 1
函数名 (参数1,参数2,...) = 函数体
// 定义方式 2
函数名 参数1 参数2.. =函数体
// 类型
函数名 :: 参数1的类型->参数2的类型->...->结果类型


说这么多,不如在编译器中感受感受:


Prelude> f3 x y z=3*x+2*y-z
Prelude> f3 1 2 3
4
Prelude> :t f3
f3 :: Num a => a -> a -> a -> a


我们惊人的发现,从定义方式 1 到 定义方式 2 的过程,就是柯里化的过程!


λ表达式



Haskell 还有另外一种书写函数的格式,即 λ 表达式;

// 定义方式 3
函数名= (\参数1 -> \参数2 -> ... ->函数体)


示例:

Prelude> f4= (\x -> \y -> x*y)
Prelude> f4 2 3
6
Prelude> f5 =(\x -> \y->4*x+5*y+1)
Prelude> f5 2 3
24


在使用一些高阶函数时,如果不想定义新函数,可以使用 λ 表达式来定义这个函数:

Prelude> map(\x->2*x+7)[1..10]
[9,11,13,15,17,19,21,23,25,27]


\x -> 2*x+7 是一个没有名字的匿名函数,在 Haskell 中,通常用 λ 表达式来构造匿名函数;


阶段小结



小结中,我们再来回归三种定义函数的方式:

// 方式 1:
f2(x,y)=4*x+5*y+1
// 方式 2:
f3 x y z=3*x+2*y-z
// 方式 3:
f4= (\x -> \y -> x*y)


函数作为 Haskell 基础之基础,牢记 3 种函数定义的方式则是基础之基础之基础。

第 1 种方式到 第 2 种方式是柯里化思想的体现。柯里化如此自然,就像呼吸一般~还有 λ 表达式,是实现匿名函数的有效方式!!


以上,真的要在编译器中敲一敲才会有更多体验。看看不同语言对于函数申明及调用的不同实现,体会函数式编程参数在函数中的输入、传递 ......


我是掘金安东尼,输出暴露输入,技术洞见生活,再会~


相关文章
|
2天前
|
Python
Python高手进阶必备:闭包与装饰器的那些不为人知的高级技巧
【7月更文挑战第6天】Python中的闭包和装饰器是提升代码质量的关键。闭包是能记住外部作用域变量的内嵌函数,常与匿名函数结合,示例展示了如何通过闭包创建具特定行为的函数。装饰器则是不修改原函数即可添加功能的语法结构,它们接收函数作为输入并返回新函数。结合使用,如参数化装饰器,能动态改变函数行为。掌握这些技巧,能增强代码可读性和复用性,推荐在实践中多加利用。
|
JavaScript 前端开发 程序员
热爱函数式的你,句句纯正的 Haskell【类型篇】
Haskell 是一门纯的函数式语言。 也就是说计算机主要是通过函数来完成的(像在数学中一样),而不是通过“先做这个,再做那个”的命令式操作顺序进行的(像在主流的编程语言中一样)。—— Simon Peyton Jones
热爱函数式的你,句句纯正的 Haskell【类型篇】
|
JavaScript 编译器
热爱函数式的你,句句纯正的 Haskell【表达式篇】
表达式是编程语言中最常用到的基础之一,本片让我们来看看在 Haskell 中表达式是怎样的?
热爱函数式的你,句句纯正的 Haskell【表达式篇】
|
JavaScript 编译器
热爱函数式的你,句句纯正的 Haskell【库函数篇】
本篇是笔记篇,介绍 Haskell 的强大的库函数,也可感受下与我们平常的 js 操作异同之处:
热爱函数式的你,句句纯正的 Haskell【库函数篇】
|
Shell BI 测试技术
Haskell 编程入门
在过去的几个月里,学习Haskell让我觉得非常快乐,但是入门的过程并没有我原先想象的那么简单。我非常幸运地在一个正确的地方工作,并且因此能够在Facebook参加Bryan O'Sullivan的Haskell课程。在Try Haskell上玩了一段时间后,最终你就会想要在自己的电脑上安装GHC了。
184 0
Haskell 编程入门
|
存储 Java 程序员
C++ 开发者快速学习 Objective-C 语言核心语法
本文将讨论 Objective-C 语言的核心语法。这部分开始详述一些具体的语法。正如你期待的一样,涉及到了定义和类。
236 0
haskell简明入门(一)
本文的主要内容参考自《Haskell趣学指南》 1. What is Haskell?     以下内容引用自Haskell官网: Haskell是一个先进的,纯粹的函数式编程语言。一个典型的声明式地,静态类型的代码如下: primes = filterPrime [2.
1479 0
|
安全 C语言
《Haskell函数式编程入门》—— 第1章,第1.6节本章小结
本节书摘来自异步社区《Haskell函数式编程入门》一书中的第1章,第1.6节本章小结,作者 张淞,更多章节内容可以访问云栖社区“异步社区”公众号查看
1518 0