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 条评论
登录 后参与评论

相关文章

来自专栏大史住在大前端

【Recorder.js+百度语音识别】全栈方案技术细节

技术栈:React+recorder-tool.js +recorder.js + Express + Baidu语音识别API

1673
来自专栏猿人谷

怎样写解释器

解释器是比较深入的内容。虽然我试图从最基本的原理讲起,尽量让这篇文章不依赖于其它的知识,但是这篇教程并不是针对函数式编程的入门,所以我假设你已经学会了最基本的 ...

1897
来自专栏光变

你所不知道的Java之Switch

??? Enum,String,Character,Byte,Short,Integer

1240
来自专栏轮子工厂

设计模式(一) | 啥是工厂模式和策略模式?

592
来自专栏desperate633

设计模式之观察者模式(Observer Pattern)现实模拟观察者模式定义观察者实现的设计原则代码实现小结

在正式介绍观察者模式前,我们先引用生活中的小例子来模拟观察者,先对观察者模式有一个整体的感觉。

762
来自专栏芋道源码1024

数据库分库分表中间件 Sharding-JDBC 源码分析 —— 分布式主键

本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2.KeyGenerator 2.1 DefaultKeyGenerator 2.2...

40714
来自专栏阿凯的Excel

Excel的匹配函数全应用

今天会和大家分享日常使用频率最高匹配函数用法,谈到匹配函数,首先想到的就是Vlookup,嗯,今天就是要分享Vlookup和他的小伙伴们的应用。 ? ...

3154
来自专栏我杨某人的青春满是悔恨

Swift API 设计指南(下)

一般来说,默认参数比方法族(method families)更可取,因为它减轻了 API 使用者的认知负担。

522
来自专栏菜鸟前端工程师

JavaScript学习笔记008-this0arguments0箭头函数

791
来自专栏web前端教室

聊一下JavaScript定时器

image.png 话说JS的定时器,常用的其实就是setTimeout和setInterval这二个。它们俩一个是运行一次就拉倒,另一个是你不叫我停我就一...

1869

扫码关注云+社区