Haskell复习笔记(一)
Haskell笔记这是第三次总结,前两次都因为各种原因丢失了,对于Haskell我算不上什么大神,只不过在大学时为了学习算法时选择了Haskell。
当时的入门书籍选择的是《Learn You Haskell》,如果你对Haskell有兴趣,它会是一个很好的选择。
编译器来这里下载https://www.haskell.org/downloads
什么是Haskell?
Haskell是一种纯函数式编程语言,在生产环境中使用的较少。
- Haskell的变量一旦定义就不会更改,比如定义变量x=5,那么变量x在程序中就只能是5,不能赋其他值。
- Haskell是惰性的,在Haskell中如果定义了一个函数,在真正需要接过前是不会求值的,比如在我们遍历一个list求和时,它会得出一个超长的加法算式,省去了一步步计算加法的时间。
- Haskell是静态类型的,在编译程序时,需要明确数据类型,同时拥有自动类型推导,类 似于python,比如定义变量a = 3+4,那么默认a就是一个整型,不需要定义。
- Haskell的代码量更少,很容易维护和读懂别人的代码。
Haskell的基本数据类型
Haskell的运算符和逻辑判断语句
基本的加减乘除没什么区别,在/运算时,返回的是浮点数
- bool代数
- True和False表示真和假。
- &&表示and(和),||表示or(或)。
- 逻辑判断语句在haskell中可以看作一个表达式使用,基本的结构是 if...then...else...,和其他语言不同的是,Haskell的then和else都要返回结果,并且不能省略。
- int表示整数,上限是2147483647,下限是-2147483648
- integer表示无限整数。
- float表示单精度的浮点数
- double表示双精度的浮点数
- bool表示布尔值,True和False。
- char表示一个字符,一组字符作为元素的list即为字符串。
List
在Haskell中,List是最常用的数据结构,和python不同的是List是单类型的数据结构,在list中只能存储多个相同类型的元素,比如一组数字。
let lst=[1,2,3,4]
字符串在Haskell中可以看作一组字符的List,如['c','u','i']和'cui'是相同的,只不过'cui'是语法糖的表示。
关于语法糖的定义:语法糖就是把原本复杂的语法结构以简单的方式表现出来,其功能不变。
字符串的合并是由"++"来连接,在对长字符串进行"++"操作时要注意,Haskell会遍历整个list,此时使用:来进行插入会更好。
在Haskell中若想取出数据使用!!,字符串索引从0开始。
"hello"++" "++"world" #"hello world"
"H":"ello" #Hello
["hello"]!!0 #hello
在Haskell中List是可以依次比较,进行比较运算的,前提是元素是可以比较的数据类型,Haskell会从头到尾进行比较,如果相等则比较下一个。
[2,3,4]>[2,3] #True
List的常用函数
- head : 返回list的头部,即首个元素。
- tail :返回list去掉头部剩余的部分。
- last : 返回list的尾部,即最后一个元素
- init : 返回list除了头部剩余的部分。
- length : 返回list的长度
- null :检查list是否为空,返回布尔值。
reverse : 将list反转并返回
take : 返回list的前几个元素,从1开始。
drop :与take相反,它会删除list的前几个元素。
maxinum和mininum :返回list中最大和最小的元素。
sum和product :返回list所有元素的和和所有元素的积。
elem : 判断一个元素是否包含于list,返回一个布尔值。
cycle :接收一个list,并返回一个无限重复原list的list。
range
学过其它语言的肯定不会陌生range,但是在Haskell中range的作用是构造list,这也是单独讲解的原因。
range不是一个函数,它是中文区间,比如[1..20]表示的是元素从1到20的list。
range可以设置不长,如[1,3,..9]表示的就是[1,3,5,7,9],包括但不限于整数,比如字母或者浮点数,但是浮点数的精度在range中可能会出问题,所以避免使用。
list表达式
list表达式是构建list另一种办法,它的基本组成结构是[输出函数 | 变量x的取值范围,变量x的筛选条件]
如取出1到10,小于5能被2整除的元素:[x|x<-[1,10],x 'mod'2==0,x>5]
list表达式的筛选条件可以是一个或多个。
list表达式的取值范围也可使是一个或多个。
Tuple
tuple(元组)一样是一种元素的容器,但是tuple在定义时就已经明确容器内元素的数量了,并且其内元素不必为同样类型。
tuple同样可以进行比较运算,但是相比较的两个元组的长度必须是完全相等的。
tuple最少拥有两个元素,拥有两个元素的tuple也叫做pair。
pair(序对)的常用函数
fst :返回一个pair的首项。
snd :返回一个pair的尾项
zip函数 :可以把两个list合并为元素为序对的list,若两个list的长度不同,则以短的为主。
Type和Typeclasses
:t命令后跟表达式,会返回它的类型,返回的结构为 表达式::类型,l类型的首字母大写。
类型变量(type variables)
使用到类型变量的函数成为多态函数,如 :t head的返回值是[a]->[a]代表head可以接受任意类型的list并返回它的第一个元素。
typeclasses
typeclasses可以理解为接口,它规定了一系列行为。
- Eq typeclasses 包含所有判断相等性的类型,提供实现的函数是==和/=,所以只要一个函数存在eq的类型限制,那么他定义时肯定==和/=。
- Ord typeclass包含可比较大小的类型,ord内包含了>,<,>=,<=等用于比较的函数,若要成为ord的成员先加入eq家族。
- Show的成员为可用字符串表示的类型,最常用的函数是show,它可以取任何一个成员类型为Show并将其转换为字符串。
- Read会将字符串进行反转,read是其最常用的函数,当回传值类型多时,需要用::来指定回传的类型。如read "4" :: Int
- Enum的成员都是连续的类型,也就是可以枚举,可迭代的,每个值都有后继子和前置子,分别可以通过succ和pred函数的到,Enum包含的类型包括Bool,Char,Ordering,Int,Integer,Float和Double。
- Bounded的成员都有其上限和下线,如Int,Bool。
- Num是表示数字的Typeclass,它的成员类型都有数字的特征。包含所有实数。
- Integral也表示数字,只包含Int和Integer。
- Floating表示浮点类型,Float和Double。
函数的语法
函数式编程语言当然核心就是函数了。
模式匹配
模式匹配从字面上理解就是对 模式 的 匹配,检查传入值是否适合从中取值进行等号后面的计算,使用模式匹配需要经过以下几个步骤。
- 声明函数的type 格式为 函数名 :typeclass 输入 ->输出
- 开始匹配模式 格式为 函数名 模式 = 函数体
chartostr :: Char ->String
chartostr 'a'="a123"
chartostr 'b'="b123"
chartostr 'c'="c123"
chartostr x ="right"
ps:就是模式匹配成功之后执行的函数,haskell一切皆函数,就像字符啊数字啊 都是函数,也可以理解为 = 后面的是回传值
list的匹配模式 (x:y),在匹配模式中没有 ++ 因为无法界定界限,使用会报错
chartostr :: [a] ->String
chartostr (a:[]) = "one ele"
chartostr (a:b:[]) = "two ele"
chartostr (a:b:_)="so long"
还有一种模式叫 as 模式 ,就是用@把模式起个名字,在之后的调用中更方便。
学习Haskell需要记住一句话 变量是变量,参数是参数。
Guards
guard就是士兵,它的特殊点在于其本身就是一个bool表达式,它的函数定义不需要等于号,而是在函数名和参数后面加上 | 函数体是一个比较算式,
maxnum :: (RealFloat a) => a -> String
maxnum x
| x < = "xiaole"
| x>="dale"
|otherwise = "duile"
可以使用where和let用来绑定变量,不过它们的定义方式和作用域不同,where的作用域是所有的guards,而let只能被使用于定义它的guards,相当于局部变量。
where绑定
和guard的 | 对齐,定义多个变量时,变量需要对齐,= 后面也可以是函数。
where name="cui"
gender="man"
age=13
也可以使用模式匹配,看起来很像解构赋值,变为:
where (name,gender,age)=("cui","man",13)
let绑定
let绑定的格式为 let binding in area ,在let定义只对area起作用 ,它是一种表达式。
Prelude> let a = 8 in a + 1
9
Case
很多的命令式编程语言都提供了case语句,case与剧中可以使用模式匹配,起始本质上来说,模式匹配就是case表达式的语法糖。比如:
head :: [a] -> a
head [] = "no head"
head [x:_] = x
-- 它们的含义是一样的
head :: [a] -> a
head xs = case xs of [] -> "no head"
[x:_] -> x
case表达式可以用在任何地方。
describeList :: [a] -> String
describeList xs = "The list is " ++ case xs of [] -> "empty."
[x] -> "a singleton list."
xs -> "a longer list."
Haskell复习笔记(一)的更多相关文章
- Haskell复习笔记(二)
Haskell中的递归 递归就是定义函数以调用自身的方式,关于递归解决问题的实例有很多,如斐波那契数列,还有汉诺塔问题,递归也正是Haskell中用来解决循环问题的关键. 自定义maxinum函数 m ...
- Java基础复习笔记系列 九 网络编程
Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...
- Java基础复习笔记系列 八 多线程编程
Java基础复习笔记系列之 多线程编程 参考地址: http://blog.csdn.net/xuweilinjijis/article/details/8878649 今天的故事,让我们从上面这个图 ...
- Java基础复习笔记系列 七 IO操作
Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...
- Java基础复习笔记系列 五 常用类
Java基础复习笔记系列之 常用类 1.String类介绍. 首先看类所属的包:java.lang.String类. 再看它的构造方法: 2. String s1 = “hello”: String ...
- Java基础复习笔记系列 四 数组
Java基础复习笔记系列之 数组 1.数组初步介绍? Java中的数组是引用类型,不可以直接分配在栈上.不同于C(在Java中,除了基础数据类型外,所有的类型都是引用类型.) Java中的数组在申明时 ...
- Java基础复习笔记基本排序算法
Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...
- Angular复习笔记7-路由(下)
Angular复习笔记7-路由(下) 这是angular路由的第二篇,也是最后一篇.继续上一章的内容 路由跳转 Web应用中的页面跳转,指的是应用响应某个事件,从一个页面跳转到另一个页面的行为.对于使 ...
- Angular复习笔记7-路由(上)
Angular复习笔记7-路由(上) 关于Angular路由的部分将分为上下两篇来介绍.这是第一篇. 概述 路由所要解决的核心问题是通过建立URL和页面的对应关系,使得不同的页面可以用不同的URL来表 ...
随机推荐
- HDU5810 Balls and Boxes
Balls and Boxes Time Limi ...
- java maven web 项目启动之后,访问所有页面为空白,不是404!!!
自己解决了大半天,后面通过解决spring单元测试的时候,发现单元测试可以用了,项目启动也可以访问页面了,具体原因不太清楚 可能原因: (1)pom.xml 依赖有重复的地方 (2)不排除与公司内网有 ...
- html5 css选择器。 井号,句号的区别
.理解CSS的样式组成CSS里的样式表是有规则组成的,每条规则有三个部分组成:1.选择器(如下面例子中的:“body”),告诉浏览器文档的哪个部分受规则影响:2.属性(如实例中的font-family ...
- QEMU KVM libvirt手册(2): monitor
Administrating Virtual Machines with QEMU Monitor When QEMU is running, a monitor console is provide ...
- 深入理解JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- select count(*) 底层究竟做了什么?
阅读本文大概需要 6.6 分钟. SELECT COUNT( * ) FROM t是个再常见不过的 SQL 需求了.在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表 ...
- Docker学习笔记-CentOS7镜像
前言: 环境:centos7.5 64 位 正文: 第一步:下载centos7镜像 docker pull centos 第二步:建立centos7的容器 sudo docker run --priv ...
- 第一节:ASP.NET开发环境配置
第一节:ASP.NET开发环境配置 什么是ASP.NET,学这个可以做什么,学习这些有什么内容? ASP.NET是微软公司推出的WEB开发技术. 2002年,推出第一个版本,先后推出ASP.NET2. ...
- Python学习笔记【第六篇】:迭代器、生成器、高阶函数、装饰器
迭代器 迭代器是访问集合元素的一种方式,迭代器从对象的第一个元素开始访问,知道所有元素被访问完成.迭代器只能往前访问,不能通过索引访问. 类型内部使用__iter__()方法转为迭代器,使用__nex ...
- vsftp搭建文档
vsftpd端口的作用:控制连接:tcp21端口用于发送FTP命令数据连接:tcp20端口用于上传下载数据 传输模式:分为主动模式和被动模式主动模式是当需要传输数据时,客户端以PORT命令告知服务器, ...