Heskell与函数式编程

导语 :这个系列打算分为三部分,由浅入深地介绍所谓的函数式编程 1)Haskell入门 2)Monad介绍 3)函数式编程的思想

Haskell简介

Haskell诞生于1990年,是一门纯函数式编程语言,和我们经常使用的JAVA不一样,JAVA是一门命令式编程语言。函数式编程和命令式编程有本质上的区别,命令式编程是基于冯诺依曼体系的抽象,通俗点来说就是像电脑运作般思考,而函数式编程更多是数学抽象上函数的概念,也就是输入和输出的映射关系。

我们来举个简单里例子,一个价格的集合,大于20块的打9折,然后相加。

下面是JAVA的示例:

这里的写法非常清晰明了,循环价格的集合,找出其中大于20的价钱,打九折,然后加到价格总数里面,实际上计算器内部使用寄存器和跳转指令执行的流程也是相差无几,这就是用计算机执行的思维去写代码。

然后看下Haskell对这个问题的处理:

就一行代码,涉及了三个函数

1)filter :从价格集合中筛选出大于20的价格,形成新的集合

2)map:对1中产生的新集合进行变换处理,这里的处理是每个元素*0.9,也就是打九折

3)sum:对2中产生集合进行求和处理

从这里可以看到,Haskell的基本处理单位是函数(函数是一等公民),一个函数可以成为另外一个函数的输入,函数和数学范畴的映射是一样的。

因此掌握Haskell对理解函数式编程具有很大的作用。

编写第一个Haskell

编写Haskell之前需要把Haskell Platform下载下来(https://www.haskell.org/platform/),安装后使用ghci就可以进行Haskell编程了。

我的电脑是Windows,在Windows下打开cmd,输入ghci,就能进入编程界面,在这个界面能够进行简单的编码,比如下面:

这里简单的进行了一次 3+5的求和操作。

但是我们更加习惯于用编辑器进行编码,下面使用文本编辑器来写一段代码。

这段代码定义了一个函数findMax,输入两个数字x和y,输出x和y的最大值,这里要注意下haskell内if else语句else是不可或缺的,不像JAVA可以只写if不写else。

写完保存成文件(这里保存为cal.hs),以.hs作为后缀,在对应目录的命令行下面输入 :l 文件名

调用自定义的函数findMax,输入参数1 3,然后就能够看到输出最大值3了。

类型和函数

Haskell是静态类型,也就是编译器在编译过程中就能够明确每个值的类型,当发现类型不匹配的时候,在编译过程中就会报错。比如输入这样一个函数:

== 是个表达式,编译的时候会进行1和”2“的类型判断,1是Int类型,”2“是[Char]类型,因此会报编译错误。

Haskell 可以使用 :t 命令来查看数值的类型,下面来看下一些常见的类型。

可以看到一些基础的类型

True ,Char,[Char]

然后对于  :t 0 的理解   ( 0 :: Num a => a ),表明 0是一种Num类族(typeclass)的a,Num类族这里可以先简单理解为JAVA的interface,Integer,Double等都是它的”实现“,和在之后的篇章再详细介绍到typeclass的概念。

我们先看下函数的类型是怎么样的,之前我们定义过一个函数findMax,这里看下

这里Ord也是一个typeclass,一个他的实例的类型能够使用>来比较大小,然后后面跟着三个a,这里简单做下括号就能够区分了。

( a -> a ) -> a ,最后一个参数输出,前面两个a是入参,用文字来描述就是:

输入两个Ord类族的参数,输出一个Ord类族的输出。

这里对findMax对下简单的变形,让它更能突显问题:

这里看下type

用文字来表述:

入参是(Ord , Ord , (Eq , Fractional) )类族的三个参数,出参是一个Boolean值,其中z具有Eq和Fractional两个特性,Eq的作用是能够做==比较,Fractional表示z能够被分解为分数。

未完待续

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java Web

《编写高质量代码》学习笔记(1)

前言 看大神推荐的书单中入门有这么一本书,所以决定把这本书的精华(自认为很有用的点),或许是我自己现在能用到的点都提炼出来,供大家参考学习。 以下内容均出自《...

3864
来自专栏小樱的经验随笔

UESTC 1599 wtmsb【优先队列+排序】

题目链接:UESTC 1599 wtmsb 题意:给你一组数,每一次取出两个最小的数,将这两个数的和放入这组数中,直到这组数只剩下一个,求最后剩下那个数的大小!...

2676
来自专栏Spark学习技巧

Flink DataStream编程指南

Flink程序是执行分布式集合转换(例如,filtering, mapping, updating state, joining, grouping, defi...

1.3K7
来自专栏小樱的经验随笔

HUST 1588 辗转数对

1588 - 辗转数对 时间限制:1秒 内存限制:128兆 155 次提交 27 次通过 题目描述假设当前有一个数对(a, b),我们可以通过一步将这个数对...

3369
来自专栏数据结构与算法

洛谷P1043 数字游戏

题目描述 丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前...

3405
来自专栏编程理解

动态规划(一):爬楼梯

时,处于原地,因为步长为 1 ~ 2 阶,不能有前进之后再后退的情况,所以只能有当前一种方式,所以

1122
来自专栏蜉蝣禅修之道

Leetcode之Longest Valid Parentheses

1322
来自专栏java一日一条

成为优秀Swift开发者的10条建议

在这里给大家分享一些帮助大家成为更优秀的Swift开发者的建议,让你的代码,写的更少,性能更优 。

1002
来自专栏数据结构与算法

BZOJ1722: [Usaco2006 Mar] Milk Team Select 产奶比赛(树形dp)

\(f[i][j]\)表示\(i\)这棵子树中答案为\(j\)的最大价值,转移的时候背包一下。。

692
来自专栏Java爬坑系列

【JAVA零基础入门系列】Day3 Java基本数据类型

  前两篇已经将开发环境搭建完成,如果你已经按之前的教程按部就班的完成了部署,那么世界上最优秀的编程语言之一和世界上最优秀的IDE之一已经出现在你的电脑上(此处...

1998

扫码关注云+社区