《Haskell趣学指南》—— 第1章,第1.1节调用函数

简介: 本节书摘来自异步社区《Haskell趣学指南》一书中的第1章,第1.1节调用函数,作者 【斯洛文尼亚】Miran Lipovaca,更多章节内容可以访问云栖社区“异步社区”公众号查看 第 1 章 各就各位,预备! Haskell趣学指南 如果你属于那种从不看前言的人,我建议你还是回头看一下本书前言的最后一节比较好。

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

第 1 章 各就各位,预备!
Haskell趣学指南
如果你属于那种从不看前言的人,我建议你还是回头看一下本书前言的最后一节比较好。那里讲解了如何使用本书,以及如何通过GHC加载函数。

首先,我们要做的就是进入GHC的交互模式,调用几个函数,以便我们简单地体验一把Haskel。打开终端,输入ghci,可以看到如下欢迎信息:

GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 

注意:
GHCi的默认命令行提示符为Prelude>,不过在本书接下来的例子中,我们将使用ghci>作为命令行提示符。若要设置你的命令行提示符与本书一致,输入:setprompt "ghci> "即可。如果不想每次打开GHCi都重新输入一遍,可以在你的home目录下创建一个.ghci文件,使它的内容为:set prompt "ghci>"。
恭喜,你已经进入了GHCi!试几个简单的运算:

ghci> 2 + 15
17
ghci> 49 * 100
4900
ghci> 1892 - 1472
420
ghci> 5 / 2
2.5

如果在同一个表达式中使用了多个运算符,Haskell会按照运算符优先级顺序执行计算。比如的优先级比-高,50100-4999就相当于(50 * 100) - 4999。

也可以通过括号来显式地指定运算次序,就像这样:

ghci> (50 * 100) - 4999
1
ghci> 50 * 100 - 4999
1
ghci> 50 * (100 - 4999) 
-244950

很酷,是吧?(哼,我知道一点也不酷,但请容许我自High一下嘛。)

有个小陷阱需要注意:只要表达式中存在负数常量,就最好用括号将它括起来。比如,执行5 -3会使GHCi报错,而5(-3)就不会有问题。

Haskell中的逻辑运算也同样直白。同许多编程语言一样,Haskell的布尔值为True与False,也有&;&;用来求逻辑与(布尔与运算)、||用来求逻辑或(布尔或运算),以及not用来对True或者False取反。

ghci> True && False
False
ghci> True && True
True
ghci> False || True
True
ghci> not False
True
ghci> not (True && True) 
False

也可以通过==与/=来判断两个值相等还是不等:

ghci> 5 == 5
True
ghci> 1 == 0
False
ghci> 5 /= 5
False
ghci> 5 /= 4
True
ghci> "hello" == "hello"
True

在同一个表达式中混用不一样的值要十分小心!如果我们输入了5+"llama"这样的代码,就会得到下面这样的出错消息了:

No instance for (Num [Char]) 
arising from a use of `+' at <interactive> :1:0-9
Possible fix: add an instance declaration for (Num [Char]) 
In the expression: 5 + "llama"
In the definition of `it': it = 5 + "llama"

GHCi 告诉我们,"llama"并不是数值,所以它不知道怎样才能给它加上5。+运算符要求它的两个参数都是数值才行。

另一方面,==可以比较任何两个可以比较的值,唯一标准就是:这两个值的类型必须相同。比如,我们如果输入True==5,GHCi就会报错。

注意:
5+4.0是合法的表达式,虽说4.0不是整数,但5既可以被看做整数也可以被看做浮点数。这样看,5与浮点数4.0的类型就匹配起来了。
到后面,我们会更加深入地学习类型。

1.1 调用函数
也许你并未察觉,从始至终我们一直都在使用函数。*就是一个函数,它可以将两个数相乘。可见,在应用(又称调用)这个函数时,我们就像夹三明治一样用两个参数将它夹在中央,这种函数被称作中缀函数(infix function)。

至于其他的大部分函数,则属于前缀函数(prefix function)。在Haskell中调用前缀函数时,先是函数名和一个空格,后跟参数列表(也是由空格分隔)。简单举个例子,我们尝试调用Haskell中最无聊的函数succ:

ghci> succ 8
9

succ函数可以取得参数的后继,前提是它要有明确的后继。一个整数的后继,就是比它大的下一个数了。

接下来尝试调用两个前缀函数min和max:

ghci> min 9 10
9
ghci> min 3.4 3.2
3.2
ghci> max 100 101
101

min和max接受两个可比较大小的参数(如数),相应地返回较大或者较小的那个数。

在Haskell中,函数应用拥有最高的优先级。因而如下两句是等效的:

ghci> succ 9 + max 5 4 + 1
16
ghci> (succ 9) + (max 5 4) + 1
16

也就是说,取9乘10的后继,简单地像下面这样写是不行的:

ghci> succ 9 * 10

因为运算有优先级,这种写法相当于先取9的后继(得到10),然后再乘以10得100。要得到正确的写法,应该改成这样:

ghci> succ (9 * 10) 

得91。
如果某函数有两个参数,也可以用反引号(`)将它括起,以中缀函数的形式调用它。比如,div函数可以用来求两个整数的商,如下:

ghci> div 92 10
9

但这种形式并不容易理解:究竟是哪个数是除数,哪个数被除数?用上反引号,按照中缀函数的形式调用它就清晰多了:

ghci> 92 div 10
9

从命令式编程走过来的程序员往往觉得函数调用离不开括号,以至于一下子无法接受Haskell的风格。其实很简单:只要见到bar (bar 3)之类的东西,就是说以3为参数调用bar函数,随后用所得的结果再次调用bar。对应的C代码大约就是这样:bar(bar(3))。

相关文章
|
1月前
|
C语言
在C语言中内部函数的应用与示例
在C语言中内部函数的应用与示例
11 2
|
2月前
|
自然语言处理 安全 Python
Python中的闭包和高阶函数详解
Python中的闭包和高阶函数详解
|
3月前
|
存储 Swift
Swift 语言:什么是闭包(Closure)?它们与函数的区别是什么?
Swift 语言:什么是闭包(Closure)?它们与函数的区别是什么?
33 1
|
9月前
|
安全 Python
Python闭包与闭包陷阱
在 Python 中,闭包是一种特殊的函数,它能够记住它所在的环境(也称作上下文)。这意味着闭包能够访问定义它的作用域中的变量。闭包通常用于封装数据和提供对外部访问的接口。
|
10月前
|
Python
|
Python
Python(5)高阶函数之返回函数和匿名函数
Python(5)高阶函数之返回函数和匿名函数
77 0
|
Go
go语言函数、方法、闭包(详解)
go语言函数、方法、闭包(详解)
77 0
|
存储 缓存 算法
【Python高级编程】—— 函数式编程总结(生成器、迭代器、匿名函数、高阶函数、返回函数、闭包、装饰器、偏函数)
Python函数式编程的一般概念及特点, 迭代器、生成器表达式、内置函数、常用高阶函数、递归与归约、实用模块和装饰器的用法, 以及避开Python严格求值顺序的变通方法、Web服务设计方法和一些优化技巧。
237 1
【Python高级编程】—— 函数式编程总结(生成器、迭代器、匿名函数、高阶函数、返回函数、闭包、装饰器、偏函数)
|
存储 Python
【Python函数式编程】——闭包
一个函数定义中引入了函数定义以外的变量,并且该函数可以在其定义以外被执行,这样的一个函数称为闭包。
137 0
【Python函数式编程】——闭包
|
算法 Python
【Python函数式编程】——返回函数
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
111 0
【Python函数式编程】——返回函数

热门文章

最新文章