感谢《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. 常用PowerShell命令

    查看版本: 文件重命名: 别名查看: 当前路径:(别名pwd) 切换路径:(别名cd) 子列表:(别名ls  -Force可查看隐藏项) 查看用户:(可显示隐藏) 资源管理器打开当前目录:(cmd亦可 ...

  2. 2018.12.1 web项目中解决乱码问题的一个工具类

    <!-- 配置一个过滤器 编码格式的过滤器 --> <filter> <filter-name>encodeFilter</filter-name> & ...

  3. 剑指offer23 从上往下打印二叉树

    没有把队列的头部弹出,出现内存错误:

  4. H5中的微信支付、支付宝支付

    微信支付的申请: 公众号支付.扫码支付等在微信公众平台.移动端的申请在微信开放平台 公众号支付流程:申请微信公众号(服务号并完成微信认证)——申请微信支付商户号(申请微信支付,资料审核通过以后,请前往 ...

  5. 【洛谷P2921】[USACO08DEC]在农场万圣节

    在农场万圣节Trick or Treat on the Farm 题目链接 题解:首先,将原图缩点,变为DAG, 然后在DAG上记忆化搜索即可 #include<iostream> #in ...

  6. Android学习笔记_53_Android界面的基本属性

    很好很全面http://www.eoeandroid.com/forum.php?mod=viewthread&tid=46859 布局: 在 android 中我们常用的布局方式有这么几种: ...

  7. ABAP术语-BOR (Business Object Repository )

    BOR (Business Object Repository ) 原文:http://www.cnblogs.com/qiangsheng/archive/2007/12/25/1013523.ht ...

  8. Keras模型的保存方式

    Keras模型的保存方式 在运行并且训练出一个模型后获得了模型的结构与许多参数,为了防止再次训练以及需要更好地去使用,我们需要保存当前状态 基本保存方式 h5 # 此处假设model为一个已经训练好的 ...

  9. 基于SpringBoot+SpringSecurity+mybatis+layui实现的一款权限系统

    这是一款适合初学者学习权限以及springBoot开发,mybatis综合操作的后台权限管理系统 其中设计到的数据查询有一对一,一对多,多对多,联合分步查询,充分利用mybatis的强大实现各种操作, ...

  10. (第02节)集成Sping框架

    通过第一节创建好的Web项目,接下来就是集成Spring框架 首先让我们看下创建好的Web项目的基本结构 其中,Java跟test是我自己创的,然后就是一般的webapp文件,和pom配置文件,要在w ...