「Haskell 学习」一 环境与大致了解
感谢《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 学习」一 环境与大致了解的更多相关文章
- 「Haskell 学习」二 类型和函数(上)
随着学习的深入,笔记会补充和修订.当然,这个补充修订也许会鸽,但我一定会坚持写完. 这个笔记假定你至少学过C/C++及Python,或与这两种语言类型相同的语言. 类型系统概述 “Haskell’s ...
- 「知识学习」二分图的最大匹配、完美匹配和匈牙利算法(HDU-2063)
定义 如果一个图\((E,V)\)的顶点集\(E\)能够被能够被分成两个不相交的集合\(X,Y\),且每一条边都恰连接\(X,Y\)中的各一个顶点,那么这个图就是一个二分图. 容易得知,它就是不含有奇 ...
- NLP领域的ImageNet时代到来:词嵌入「已死」,语言模型当立
http://3g.163.com/all/article/DM995J240511AQHO.html 选自the Gradient 作者:Sebastian Ruder 机器之心编译 计算机视觉领域 ...
- 从0开始学习 GITHUB 系列之「GIT 速成」【转】
本文转载自:http://stormzhang.com/github/2016/05/30/learn-github-from-zero3/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...
- 从0开始学习 GITHUB 系列之「加入 GITHUB」【转】
本文转载自:http://stormzhang.com/github/2016/05/26/learn-github-from-zero2/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...
- 「C语言」Windows+EclipseCDT下的C语言开发环境准备
之前写过一篇 「C语言」在Windows平台搭建C语言开发环境的多种方式 ,讨论了如何在Windows下用DEV C++.EclipseCDT.VisualStudio.Sublime Test.Cl ...
- DDD 实战记录——实现「借鉴学习计划」
「借鉴学习计划」的核心是:复制一份别人的学习计划到自己的计划中,并同步推送学习任务给自己,并且每个操作都要发送通知给对方. 它们的类图如下: 它们的关系是一对多: // Schedule entity ...
- 有些lambda表达式就可以体现出编程中「Context(上下文)」环境
编程中什么是「Context(上下文)」? 每一段程序都有很多外部变量.只有像Add这种简单的函数才是没有外部变量的.一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行.你为了使他们运行 ...
- Note -「Lagrange 插值」学习笔记
目录 问题引入 思考 Lagrange 插值法 插值过程 代码实现 实际应用 「洛谷 P4781」「模板」拉格朗日插值 「洛谷 P4463」calc 题意简述 数据规模 Solution Step 1 ...
随机推荐
- [19/03/23-星期六] 容器_ 泛型Generics
一.概念 生活中的容器不难理解,是用来容纳物体的,程序中的“容器”也有类似的功能,就是用来容纳和管理数据. 数组就是一种容器,可以在其中放置对象或基本类型数据. ---优势:是一种简单的线性序列,可以 ...
- python常见异常及解决方法
异常1: ValueError: unsupported hash type sha224 ERROR:root:code for hash sha256 was not found. Traceba ...
- Git使用(一)
声明: 第一次使用git,只能保证我的方法可以用,肯定不是最简最好的.以后需要用到更多的用法的时候再来这里更新. 说实话,记下来主要是因为自己记性不好,各种配置记不住,都是当备忘录用的,(囧囧囧囧囧) ...
- JavaEE权限管理系统的搭建(四)--------使用拦截器实现登录认证和apache shiro密码加密
RBAC 基于角色的权限访问控制(Role-Based Access Control)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.在一个 ...
- 开始重学java【门头沟2017年12月6日】
现在从struts2开始重新学习java, 想找个人一起学习java/php都可以. 学习时间大概是两个月,就是年前这段时间. 下一个阶段就是做项目进行练习.(时间为:一个月时间) 不管是学习java ...
- mui 的多图片上传
pickHead(){ var _this = this; plus.gallery.pick(function(path){ _this.headImage=path; var files = [{ ...
- Unity 游戏框架搭建 (九) 减少加班利器-QConsole
为毛要实现这个工具? 在我小时候,每当游戏在真机运行时,我们看到的日志是这样的. 没高亮啊,还有乱七八糟的堆栈信息,好干扰日志查看,好影响心情. 还有就是必须始终连着usb线啊,我想要想躺着测试... ...
- linux下ssh/sftp配置和权限设置
基于 ssh 的 sftp 服务相比 ftp 有更好的安全性(非明文帐号密码传输)和方便的权限管理(限制用户的活动目录). 1.开通 sftp 帐号,使用户只能 sftp 操作文件, 而不能 ssh ...
- 使用DOM对表格进行增删
---恢复内容开始--- 声明本文旨在练习dom 其中可以链接数据 或者使用ajax 实现的我全用的dom因为我在学dom. 一. 表格构建 <section id="section_ ...
- linux下进程的最大线程数、进程最大数、进程打开的文件数
linux下进程的最大线程数.进程最大数.进程打开的文件数 ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_TH ...