【Haskell】Haskell学习笔记 基础知识总结(持续更新!)_memcpy0的博客-程序员宝宝_haskell技术大全

技术标签: 编程语言和语言哲学  


0. 简介和准备

Haskell是一门声明式、函数式的编程语言,相比起命令式编程,它的代码相当简洁、表达力强。一个示例是Haskell写的八皇后:

safe :: Int -> [Int] -> Int -> Bool
safe _ [] _ = True
safe x (x1:xs) n = x /= x1 && x /= x1 + n && x /= x1 - n && safe x xs (n+1)

queens :: Int -> [[Int]]
queens 0 = [[]]
queens n = [ x:y | y <- queens (n-1), x <- [1..8], safe x y 1]

要做的准备是,按照Windows10下VS Code配置Haskell语言环境这篇文章,在Windows下搭建一个VS Code+Stack+GHC的语言学习环境。

然后在VS Code中新建一个 test.hs ,并在其所处文件夹打开终端,输入 stack exec ghci 或者 stack exec -- ghci 或者 stack --compiler ghc-8.0.2 exec ghci 或者 stack --compiler ghc-8.0.2 exec -- ghci ,进入Haskell解释器环境。


1. 基础语法

函数

test.hs 中输入:

doublex x = x + x

然后在REPL中导入这个Haskell文件,在终端使用这个 doublex 函数:

Prelude> :l test
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> doublex 5
10

类似的,duoblex x 可以看作是函数名传入的参数= 后面则是函数返回值。相当于:

def doublex(x):
	return x + x

更进一步的,我们在函数 doublexy 中调用我们写的函数 doublex

doublex x = x + x
doublexy x y = doublex(x) + doublex(y)

导入终端后,调用 doublexy 函数,传入 5 4 ,相当于 5 * 2 + 4 * 2 = 18

*Main> :l test
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> doublexy 5 4
18

列表

列表的定义和Python差不多:

numbers = [1, 3, 4, 5]

导入后输出这个列表:

*Main> numbers
[1,3,4,5]

列表拼接 ++

在终端输入以下代码,发现输出了 [1, 3, 4, 5, 7, 10]

*Main> [1, 3, 4, 5] ++ [7, 10]
[1,3,4,5,7,10]

Haskell中用 "abcde" 表示一个字符串,不过字符串其实是列表的语法糖"abcde" 其实是 ['a', 'b', 'c', 'd', 'e'] 。更进一步,列表本身也是一个语法糖[1, 3, 4, 5] 其实是 1 : 3 : 4 : 5 : [] 的语法糖,[] 表示一个空列表。不信可以在终端输入代码:

*Main> ['a', 'b', 'c']
"abc"
*Main> 1:3:4:5:[]
[1,3,4,5]

另外,2 : [3, 4, 5] 是正确的,而 [2, 3, 4] : 5 是错误的。

*Main> 2 : [3, 4, 5]
[2,3,4,5]
*Main> [2, 3, 4] : 5 

<interactive>:16:1: error:
    ? Non type-variable argument in the constraint: Num [[t]]
      (Use FlexibleContexts to permit this)
    ? When checking the inferred type
        it :: forall t. (Num [[t]], Num t) => [[t]]

在列表的头部插入元素,比在尾部插入元素快很多

列表取值 !!

[...] !! t 表示从列表中取出第 t 个元素,下标从零开始:

*Main> [23, 7, 52, -1] !! 3
-1     
*Main> [23, 7, 52, -1] !! 0
23     
*Main> [23, 7, 52, -1] !! 9
*** Exception: Prelude.!!: index too large

列表比较

列表之间可以通过 >, <, >=, <= 来比较列表大小,标准是字典序。还可以通过 ==, != 来判断列表是否相等。

列表常用函数

有如下常用函数:
head 用于返回列表头部元素,tail 为列表去掉 head 后的部分。
init 返回列表去掉 last 后的部分,last 返回列表尾部元素。
length 返回列表长度,null 检查列表是否为空,
reverse 反转列表,take 用一个整数做参数,返回一个列表的前几个元素,drop 用一个整数做参数,返回删除前几个元素之后的列表,cycle 用一个列表做参数,返回又给由其无限循环组成的列表,repeat 用一个整数作为参数,返回由这个数无限循环组成的列表。

*Main> numbers
[1,3,4,5]
*Main> head numbers
1
*Main> tail numbers
[3,4,5]
*Main> init numbers
[1,3,4]
*Main> last numbers
5
*Main> length numbers
4
*Main> null numbers
False
*Main> reverse numbers
[5,4,3,1]
*Main> numbers
[1,3,4,5]
*Main> take 2  numbers 
[1,3]
*Main> drop 2  numbers 
[4,5]

区间表示

[1..20] 会返回1~20的列表,[2,4..30] 会返回2~30中所有偶数的列表,[1,3..] 返回所有奇数——不过Haskell是惰性求值,所以不会真正生成无限多的元素,而是当你需要时求值,比如 take 10 [1,3..] 返回这个无限列表中的前十个元素。

*Main> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
*Main> [2, 4..30]
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30]
*Main> [1,3..11]
[1,3,5,7,9,11]
*Main> take 10 [1,3..]
[1,3,5,7,9,11,13,15,17,19]

列表推导

有点类似与Python的列表推导式,在列表中用一个 | 分隔开,前面写参数的表达式,后面用属于符号 <- 写参数的取值范围,Haskell会自动返回取值范围内、参数通过表达式计算出的值组成的列表。

比如 [x * 2 | x <- [1..10]] 返回一个2~20的偶数组成的列表;还可以写多个取值范围、逻辑表达式、if表达式:

*Main> [x * 2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]
*Main> [x | x <- [50..100], x `mod` 7 == 3] 
[52,59,66,73,80,87,94]

还可以写一个函数 boomborg ,传入一个列表参数 ls ,当参数 x 属于这个列表 ls 并且 x 是奇数时,使用参数的表达式——如果 x < 10 就生成 boom 、否则生成 borg

boomborg ls = [if x < 10 then "boom" else "borg" | x <- ls, odd x]

导入后调用该函数,用列表做参数:

*Main> :l test
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main. 
*Main> boomborg [1..20]  
["boom","boom","boom","boom","boom","borg","borg","borg","borg","borg"]
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/myRealization/article/details/118979596

智能推荐

python3 asyncio原理_Python异步编程模块asyncio学习 !此模块非常之重要!_家庭影院的博客-程序员宝宝

asyncio是Python3.4引入的一个标准库,直接内置了对异步IO的支持。asyncio模块提供了使用协程构建并发应用的工具。它使用一种单线程单进程的的方式实现并发,应用的各个部分彼此合作, 可以显示的切换任务,一般会在程序阻塞I/O操作的时候发生上下文切换如等待读写文件,或者请求网络。同时asyncio也支持调度代码在将来的某个特定事件运行,从而支持一个协程等待另一个协程完成,以处理系统信...

【高效程序员系列】1、好马配好鞍——舒适的工作环境_setsailgo的博客-程序员宝宝

本篇有点发牢骚的感觉,呵呵,如果你的工作环境不舒服,就和我一起发发牢骚吧,否则可以略过本篇。软件开发人员的劳动成果是什么?软件。往细了说,就是代码。代码是如何产生的?是我们经过思考得出的解决问题的方法,然后通过敲击键盘和点击鼠标产生的文件。所以代码只是一种表现形式,最重要的是

maven之pom深入_effective pom_月疯的博客-程序员宝宝

maven是一款(构建管理)和(依赖管理)的工具。Maven本身定位是一款(项目管理工具)有效pom翻译为effective POM,在pom的继承关系中,子pom可以覆盖父pom中的配置;如果子pom没有覆盖,那么父pom中的配置将会被继承。按照这个规则,继承关系中的所有pom叠加到一起,就生成一个最终生效的pom。显然maven实际运行的过程中,执行构建操作是按照这个最终生成的pom运行起来的。运行有效pom的命令:mvn help:effective-pom我们使用和配置的P

python中value的含义_python中value的意思_高步步的博客-程序员宝宝

python语句s = str(value)是什么意思呢把value转成字符串,然后赋值给变量s 比如说,s=str(100)以后。Python 比如有一串数据的话里面 value[:-1]是什么value[:-1] : value 应该是一个列表/元组, value[:-1]表示其最后一个元素python 如何将字典中的value值CSS布局HTML小编今天和大家分享和如图一数据,如何将字典中的..._1671465600

PHP数组函数 array_values (返回数组中所有的值)_ztnhnr的博客-程序员宝宝

在PHP中,数组函数 array_values() 用来返回包含数组中所有的值的数组。函数语法:array_values(array$array):array函数参数说明:参数 描述 array 必需。规定数组。 array_values() 函数返回包含数组中所有的值的数组。被返回的数组将使用数值键,从 0 开始且以 1 递增。举例,返回数组中所有值的数组: &lt;?php//定义数组$ar...

随便推点

python中高阶函数之filter(),reduce(),map()的使用_和小胖的博客-程序员宝宝

        学习python大家都知道,python有形形色色的库能给我们的开发工作带来很大的方便,同样也有一些函数如果用起来也能够大大的提高我们的效率,这次我们就来认识一下python的几个高阶函数。filter(function_or_none, sequence)函数 :顾名思义就是起到一个过滤作用,它的作用就是会对你传入其中的数组的元素按照特定的函数处理后再返回一个数组,这个处理的函数...

labelimg标注格式转labelme标注格式,并读取imageData信息_amazarashi_yyh的博客-程序员宝宝_labelimg转labelme

在用CenterNet模型训练自己的数据集时,发现需要coco数据集格式,即需要labelme标注得到的json文件,但由于我是使用labelimg进行标注,所以只有xml文件。于是开始寻找

数学专业考研学计算机,科学网—数学专业考研的那些事 - 苏先锋的博文_黏人的小妖精的博客-程序员宝宝

数学类的研究生专业基础数学,应用数学,概率论与数理统计,计算数学,运筹学与控制论和数学教育(具体情况见附录1)。根据自己的实际情况选择相应的专业。考数学类专业,很多学校两门专业课一般是数学分析和高等代数(当然各个学校要求的不一样),数学教育可能会有所区别,均为高校自主命题。考研常识数学专业考研分统考课和专业课,各两门。统考政治必考,另一门课一般专业考英语或其它外语如日语、法语、俄语等。分值分布为政...

python设置unicode编码,Python Unicode编码_weixin_39586649的博客-程序员宝宝

I am using argparse to read in arguments for my python code. One of those inputs is a title of a file [title] which can contain Unicode characters. I have been using 22少女時代22 as a test string.I need t...

深度神经网络(DNN)是否模拟了人类大脑皮层结构?_woshicver的博客-程序员宝宝

链接:https://www.zhihu.com/question/59800121编辑:深度学习与计算机视觉声明:仅做学术分享,侵删作者:SIY.Zhttps://www.zhihu....

UVA-489 刽子手游戏 题解答案代码 算法竞赛入门经典第二版_漂流瓶jz的博客-程序员宝宝

https://github.com/jzplp/aoapc-UVA-Answer#include&lt;cstring&gt;#include&lt;cstdio&gt;#define MAXN 10010char s[MAXN], st[MAXN];bool vis[MAXN];int main() { int t,i,j,k,len; char c; bool f...

推荐文章

热门文章

相关标签