感谢《Real World Haskell》在网上的免费发布,可以白嫖学Haskell这个久闻大名的函数式编程语言了。

本文运行于openSUSE Tumbleweed下,运行相关命令时留意。

安装

Linux下想搞和编程相关的事情非常简单,至少比配置游戏要简单。

sudo zypper in ghc

ghc即Glasgow Haskell Compiler,一个主流的编译器。也支持python式的互动执行(ghci)。笔者运行时该编译器已经是8.0.2版本了。

运行

输入ghci,会进入Haskell的interactive interpreter。大概的运行界面如下:

# zuiho @ zuiho-pc in ~ [Time]
$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude>

根据书中的说法,“The word Prelude in the prompt indicates that Prelude, a standard library of useful functions, is loaded and ready to use. When we load other modules or source files, they will show up in the prompt, too.”即prelude是一个基本模块,初始情况会加载它。而如果加载了其它模块,那么会变成这样:

Prelude> :module + Data.Ratio
Prelude Data.Ratio>

可想而知,如果加载了114514个模块,那么长度会比较麻烦(但好处是告诉运行者加载了哪些模块)。这本书里面建议了一个方法,来避免这个可能的情况出现:

Prelude Data.Ratio> :set prompt "ghci> "
ghci>

基本功能

计算器

可以当计算器使用,除法不去尾,^与**作为幂次进行计算(前者后跟整数,后者后跟浮点数)。值得一提的是,支持前缀表达式,只要给操作符加上括号:

ghci> (+) 2 2
4

而Haskell中的“-”是一个一元操作符,也就是说,-3的意思是一个数字3再加上前面的减法操作符。这意味着这样的操作会出现问题:

ghci> 22 + -33

<interactive>:3:1: error:
Precedence parsing error
cannot mix ‘+’ [infixl 6] and prefix `-' [infixl 6] in the same infix expression

想要使用熟悉的负数必须这么用:“6+(-(1/3))”。这样做的原因在于,Haskell内应用函数的方法类似这样:“f 4”。那么如果出现“f -3”就会出现歧义:这个f到底是变量还是函数?这个-3是参数吗?类似的道理,如果输入“2*-3”同样会报错,因为编译器会把*-当作一个参数。这些和负数相关的东西需要我们记住。

布尔值、比较操作符

布尔值(True/False)不能同1与0直接等价,二者相比较会出现错误(相关内容见下报错信息)。逻辑与与逻辑或的操作符号分别为&&与||。Haskell里,逻辑操作符的参数必须为Bool型。
各种比较操作符(comparison operator)返回bool值。Haskell里的不等于是/=,类似≠≠;其逻辑非的操作符是not而不是!。

预设值与赋值

一部分变量是有预设值的,如ππ,是可以直接通过pi来访问的。但是e不是。利用let语句我们可以给变量赋值。

ghci> let e = exp 1

注意,这里的exp是内嵌函数,而Haskell的特色就是调用函数不加括号。

进一步了解

实际上,在上面的探索过程中,至少笔者本人已经会遇到一些报错信息。这个时候可以去浏览网上的帮助文档来解决自己的疑难。Haskell给的报错信息是很有条理的,至少不会一个错爆出来十几个Error和四五十个Note。

列表及其操作

列表类似python的语法([1,2,3]),但是其内部成员类型应当一致。同样,我们可以利用类似pascal的语法来声明一个列表:

ghci> [1..10]
[1,2,3,4,5,6,7,8,9,10]

..表示枚举,它只适用于可枚举的对象,形成一个闭区间。比如说你对”angry”和”excited”枚举是无意义的。
利用这种语法可以写出各种骚序列:

ghci> [1.0,1.25..2.0]
[1.0,1.25,1.5,1.75,2.0]
ghci> [1,4..15]
[1,4,7,10,13]
ghci> [10,9..1]
[10,9,8,7,6,5,4,3,2,1]

给定的第一、第二项决定了公差(对于浮点数,请注意浮点数误差问题)。注意第二种情况,由于13+3=16>15,并没有把15/16给进去。

列表间操作

连接两个列表用++符号。在列表头加入一个元素用:符号。具体的示例见下:

ghci> [] ++ [False,True] ++ [True]
[False,True,True]
ghci> 1:[5,5,1]
[1,5,5,1]

你可以试试[1,5,5]:1会发生什么,反正结果蛮气人的。

字符(串)

双引号规定字符串。接受转义字符。putStrLn输出一字符串。单引号规定字符。实际上,双引号和由单引号构成的列表似乎是等价的:

ghci> let a = ['l', 'o', 't', 's', ' ', 'o', 'f', ' ', 'w', 'o', 'r', 'k']
ghci> a
"lots of work"
ghci> a == "lots of work"
True

这样,适用于列表的操作应当亦适用于字符串。

一个实际的程序

-- file: WC.hs
-- lines beginning with "--" are comments. main = interact wordCount
where wordCount input = show (length (lines input)) ++ "\n"

“–”如所见,两个连杠是注释的标志。将这段程序保存到WC.hs文件中,你想要处理的输入保存到一文件中,然后运行它(runghc WC < I_am_a_input.txt),它会计算输入的内容的行数。这段操作的原理后面会提及。

「Haskell 学习」一 环境与大致了解的更多相关文章

  1. 「Haskell 学习」二 类型和函数(上)

    随着学习的深入,笔记会补充和修订.当然,这个补充修订也许会鸽,但我一定会坚持写完. 这个笔记假定你至少学过C/C++及Python,或与这两种语言类型相同的语言. 类型系统概述 “Haskell’s ...

  2. 「知识学习」二分图的最大匹配、完美匹配和匈牙利算法(HDU-2063)

    定义 如果一个图\((E,V)\)的顶点集\(E\)能够被能够被分成两个不相交的集合\(X,Y\),且每一条边都恰连接\(X,Y\)中的各一个顶点,那么这个图就是一个二分图. 容易得知,它就是不含有奇 ...

  3. NLP领域的ImageNet时代到来:词嵌入「已死」,语言模型当立

    http://3g.163.com/all/article/DM995J240511AQHO.html 选自the Gradient 作者:Sebastian Ruder 机器之心编译 计算机视觉领域 ...

  4. 从0开始学习 GITHUB 系列之「GIT 速成」【转】

    本文转载自:http://stormzhang.com/github/2016/05/30/learn-github-from-zero3/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...

  5. 从0开始学习 GITHUB 系列之「加入 GITHUB」【转】

    本文转载自:http://stormzhang.com/github/2016/05/26/learn-github-from-zero2/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...

  6. 「C语言」Windows+EclipseCDT下的C语言开发环境准备

    之前写过一篇 「C语言」在Windows平台搭建C语言开发环境的多种方式 ,讨论了如何在Windows下用DEV C++.EclipseCDT.VisualStudio.Sublime Test.Cl ...

  7. DDD 实战记录——实现「借鉴学习计划」

    「借鉴学习计划」的核心是:复制一份别人的学习计划到自己的计划中,并同步推送学习任务给自己,并且每个操作都要发送通知给对方. 它们的类图如下: 它们的关系是一对多: // Schedule entity ...

  8. 有些lambda表达式就可以体现出编程中「Context(上下文)」环境

    编程中什么是「Context(上下文)」?   每一段程序都有很多外部变量.只有像Add这种简单的函数才是没有外部变量的.一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行.你为了使他们运行 ...

  9. Note -「Lagrange 插值」学习笔记

    目录 问题引入 思考 Lagrange 插值法 插值过程 代码实现 实际应用 「洛谷 P4781」「模板」拉格朗日插值 「洛谷 P4463」calc 题意简述 数据规模 Solution Step 1 ...

随机推荐

  1. 八、IntelliJ IDEA 缓存和索引的介绍及清理方法

    这样一句话“ 对于首次创建或打开的新项目,IntelliJ IDEA 都会创建项目索引,大型项目在创建索引的过程中可能会出现卡顿的现象,因此强烈建议在 IntelliJ IDEA 创建索引的过程中不要 ...

  2. 【luogu P3931 SAC E#1 - 一道难题 Tree】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3931 肉眼观察题目感觉可以跑最大流. 证明是如果拆断一棵树,可以最小割,最小割等于最大流. 注意: 图是无向 ...

  3. 【luogu P1268 树的重量】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1268 给定所有点间的最短路求原图所有路径和 形如: 我们需要计算红边+绿边 绿边 = (红边+蓝边+紫边)/ ...

  4. CGAL 4.6 - Surface Reconstruction from Point Sets

    http://doc.cgal.org/latest/Surface_reconstruction_points_3/ The following example reads a point set, ...

  5. SqlSugar操作Oracle的dblink时候@符号问题

    用的这个版本,作者忘记删除Oracle中的代码了....下个版本作者应该就会更新了,到时候就不会存在这个问题,这里记录一下. 引用nuget出现的问题: 使用dblink的时候,查询的时候需要带@符号 ...

  6. Mac改变系统截图存储路径

    时间:2018年9月13日 人物:同事和我 事情:看苹果秋季新品发布会,并且想要截图下来当时的新品介绍. 问题:系统的截图默认是存储在桌面,整理的时候,不是很方便. Mac截图快捷键: 截取选中区域: ...

  7. JSON Web Tokens介绍

    转载请标明出处: http://blog.csdn.net/forezp/article/details/72804324 本文出自方志朋的博客 ##什么是JWT 这篇文章选择性翻译于https:// ...

  8. jdk下载安装

    1.下载地址:https://www.oracle.com 注册,登陆,选择版本下载(注意,下载时提示you must accept the license agreement before down ...

  9. JavaScript 基础(一)

    基本语法: 区分大小写: ECMAScript 中的一切(变量,函数名和操作符)都区分大小写. 标识符: 表示符就是指,变量,函数,属性名字,或者函数的参数. 1.第一个字符必须是一个字母,下划线(_ ...

  10. oracle-sql优化-通过分组和缓存减少不必要的读

    环境:aix 7.1,oracle12.1.0.2 cdb 优化前SQL select * from (select row_.*, rownum rownum_ from (select '弱覆盖' ...