本节书摘来自异步社区《Haskell趣学指南》一书中的第1章,第1.2节小朋友的第一个函数,作者 【斯洛文尼亚】Miran Lipovaca,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.2 小朋友的第一个函数
函数的声明与它的调用形式大体相同,都是先函数名,后跟由空格分隔的参数表。不过后面多了个等号(=),并且后面的代码定义了函数的行为。

举个例子,我们先写一个简单的函数,让它将一个数字乘以2。打开你最喜欢的编辑器,输入如下代码:

doubleMe x = x + x

将它保存为baby.hs或者任意名称,然后转至文件所在目录,打开GHCi,执行:l baby装载它。随后就可以跟我们的函数小朋友玩耍了:

ghci> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )
Ok, modules loaded: Main.
ghci> doubleMe 9
18
ghci> doubleMe 8.3
16.6

+运算符对整数和浮点数都可用(实际上所有有数字特征的值都可以),所以我们的函数可以处理一切数值。

接下来声明一个取两个参数的函数,让它分别将两个参数乘以2再相加。修改baby.hs,将如下代码加到后面:

doubleUs x y = x * 2 + y * 2

注意:
Haskell中的函数定义并没有顺序的概念,所以baby.hs中函数定义的先后对程序没有任何影响。
将它保存,在GHCi中输入:l baby再次装载。测试它的结果是否符合预期:

ghci> doubleUs 4 9
26
ghci> doubleUs 2.3 34.2
73.0
ghci> doubleUs 28 88 + doubleMe 123
478

你也可以在函数中调用其他的函数,如此一来我们可以将doubleUs函数改为:

doubleUs x y = doubleMe x + doubleMe y

这种模式在Haskell中十分常见:编写一些明显正确的简单函数,然后将它们组合起来,形成一个较为复杂的函数。这是减少重复工作的金科玉律。设想,如果哪天有个数学家验证说2其实该是3,我们该怎么改?在这里,我们只需要将doubleMe改为x+x+x即可,由于doubleUs调用doubleMe,于是整个程序便轻松进入2即是3的古怪世界。

下面我们再编写一个函数, 它将小于等于100的数都乘以2 (因为大于100的数都已经足够大了)。

doubleSmallNumber x = if x > 100then xelse x*2

这个例子就引出了Haskell的if语句。你也许已经对其他语言的else很熟悉,不过Haskell的if语句的与众不同之处就在于,else部分是不可省略的。

在命令式语言中,程序的执行就是一步又一步的操作,if语句可以没有else部分,如果条件不符合,就直接跳过这一步。因此,命令式语言中的if语句可以什么都不做。

而在Haskell中,程序是一系列函数的集合:函数取数据作为参数,并将它们转为想要的结果。每个函数都会返回一个结果,也都可以为其他函数所用。既然必须返回结果,那么每个if就必须同时跟着一个else,不管条件满足还是失败,都需要返回一个结果。一言以蔽之,Haskell中的if是一个必然返回结果的表达式(expression),而非语句(statement)。

假如我们想让之前的doubleSmallNumber函数的结果都加1,新的函数的定义将是如下的模样:

doubleSmallNumber' x = (if x > 100 then x else x*2) + 1

可以留意这里括号的使用,如果忽略掉括号,函数就会只在x小于等于100时给结果加1了。另外,也可以留意函数名最后的那个单引号,它没有任何特殊含义,只是一个函数名的合法字符罢了。通常我们会使用单引号来区分这是某函数的严格求值(与惰性求值相对)版本,或者是一个稍经修改但差别不大的函数。

既然'是合法字符,定义这样的函数也是可以的:

conanO'Brien = "It's a-me, Conan O'Brien!" 

在这里有两点需要注意。首先就是我们没有大写Conan的首字母,因为函数是不能以大写字母开始的(我们将在后面讨论其原因 0,另外就是这个函数并没有任何参数。没有参数的函数通常被称作定义或者名字,在函数被定义之后我们就再也不能修改它的内容,conanO'Brien从此与字符串"It's a-me, Conan O'Brien!"完全等价。

《Haskell趣学指南》—— 第1章,第1.2节小朋友的第一个函数相关推荐

  1. 《Haskell趣学指南》—— 第2章,第2.3节类型变量

    本节书摘来自异步社区<Haskell趣学指南>一书中的第2章,第2.3节类型变量,作者 [斯洛文尼亚]Miran Lipovaca,更多章节内容可以访问云栖社区"异步社区&quo ...

  2. 《Haskell趣学指南》笔记之I/O

    系列文章 <Haskell趣学指南>笔记之基本语法 <Haskell趣学指南>笔记之类型(type) <Haskell趣学指南>笔记之函数 <Haskell趣 ...

  3. [2017.02.21-22] 《Haskell趣学指南 —— Learning You a Haskell for Great Good!》

    {- 2017.02.21-22 <Haskell趣学指南 -- Learning You a Haskell for Great Good!> 学习了Haskell的基本语法,并实现了一 ...

  4. Haskell趣学指南4-6

    函数的语法 模式匹配 本章讲的就是haskell那套酷酷的语法结构,先从模式匹配开始.模式匹配通过检查数据的特定结构来检查其是否匹配,并按模式从中取得数据. 在定义函数时,你可以为不同的模式分别定义函 ...

  5. 【趣学算法】第二章 算法之美(下)

    14天阅读挑战赛 [趣学算法]第二章 算法之美(下) 1. 一棋盘的麦子 1.1 题目描述 1.2 题目解析 1.3 爆炸增量函数 称上面的函数(1.2中的第一个函数)为爆炸增量函数. 爆炸函数也就是 ...

  6. 趣学数据结构--第六章:树

    趣学数据结构---->第六章:树 二叉树 线索二叉树 树的应用 二叉树的深度 二叉树的叶子数 二叉树的结点数 三元组创建二叉树 遍历序列还原树 哈夫曼树 二叉树 二叉树的创建(询问创建以及补空创 ...

  7. HTML5 权威指南第 10 章 文档分节 学习笔记

    HTML5 权威指南第 10 章 文档分节 学习笔记 第 8 章 标记文字 内容从从文字出发,专注如何将单体内容正确的呈现出来:第 9 章 组织内容 内容从段落出发,专注如何将单体内容合理的放在段落中 ...

  8. 《趣学CCNA——路由与交换》——6.1节Cisco设备的管理与配置

    本节书摘来自异步社区<趣学CCNA--路由与交换>一书中的第6章,第6.1节Cisco设备的管理与配置,作者 田果 , 彭定学,更多章节内容可以访问云栖社区"异步社区" ...

  9. 《趣学CCNA——路由与交换》——2.3节网络层协议概述

    本节书摘来自异步社区<趣学CCNA--路由与交换>一书中的第2章,第2.3节网络层协议概述,作者 田果 , 彭定学,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

最新文章

  1. 【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解
  2. Android布局中 android:layout_gravity=bottom为何不起作用?
  3. 进入保护模式(二)——《x86汇编语言:从实模式到保护模式》读书笔记14
  4. npoi 设定视图为分页预览_按班级分页打印,只要两步就行,不需要再筛选复制打印了...
  5. C++ 标准文件的写入读出(ifstream,ofstream)
  6. 起泡排序算法及其算法的验证
  7. 杭州之行--记杭电网新恩普杯程序设计邀请赛
  8. 阿里巴巴的AI“发动机”
  9. 进销存管理系统是什么?能给企业带来哪些好处?
  10. 计算机硬盘能否做u盘用怎么用,教你怎么用移动硬盘做原系统的启动硬盘图文教程...
  11. cmos电路多余输入端能否悬空_CMOS电路不使用的输入端不能悬空
  12. springboot 实现图片合并
  13. 阿里云大数据ACP认证学习笔记
  14. 华为p20nfc怎么复制门禁卡_华为荣耀手机的NFC功能怎么用?怎么刷门禁卡
  15. 面向对象[方法]定义一个长方形类,定义 求周长和面积的方法
  16. week11作业——C - 必做题11-3
  17. Qt中鼠标的双击事件和单击事件的实现方式
  18. 对数正态分布均值和方差控制着正态分布什么
  19. python 3.10上安装pyqt5
  20. 诗经 - 小雅 - 杕杜

热门文章

  1. ThreadLocal源码分析
  2. DEDECMS教程:上/下一篇文章标题长度的截取方法
  3. 数据还原到指定时间点的处理示例
  4. windows server 2012 用sysdba登录报错 ORA-01031
  5. 开发自己的山寨Android注解框架
  6. Could not apply the stored configuration for monitors 解决办法
  7. vim的寄存器和剪贴簿操作?
  8. sed awk 笔记(二)
  9. “微信应用号对行业影响”之一,app开发速来围观
  10. VC6迁移到VS2008几个问题——良好的代码,从我做起,从现在开始。