Haskell tutorial -- Chapter5(模组Modules)

Haskell tutorial -- Chapter5(模组Modules)

latest edition:8/1/2020

讲到最后终于讲到模组啦(看看心情讲不讲IO,因为我觉得我不是很够格,如果我再整理一下觉得我自己理解还可以,不会把大家带到坑里面的话,我就把IO也写了吧,毕竟要出就出全哈哈哈哈),本篇文章源产自2019年的最后一天,算是跨时代的产物,之后由于学习java(现在学到对象啦)耽误了一段时间,现在继续开始更新这个系列(之后可能会继续出Java的教程或者出Haskell的IO以及后面的知识点)。那我们这章要做什么事情呢?我们这章把早就应该讲的模组讲一下吧。


一丶介绍

(1)首先先说一下模组的定义:

Haskell 中的模组是含有一组相关的函数,类型和类型类的组合。而 Haskell 程序的本质便是从主模组中引用其它模组并调用其中的函数来执行操作。这样可以把源代码分成多块,只要一个模组足够的独立,它里面的函数便可以被不同的程序反复重用。这就让不同的源代码各司其职,提高了源代码的健壮性。
Haskell 的标准库就是一组模组,每个模组都含有一组功能相近或相关的函数和类型。有处理 List 的模组,有处理并发的模组,也有处理复数的模组,等等。目前为止我们谈及的所有函数, 类型以及类型类都是 Prelude模组的一部分,它缺省自动装载。在本章,我们看一下几个常用的模组,在开始浏览其中的函数之前,我们先得知道如何装载模组.
----《Haskell趣学》


到目前为止呢,我们学的所有类,类型类,函数都是prelude模组的一部分,他缺省(默认)自动装载了,这也是为什么大家不用去导入这些模组的原因!但是除开这些,当我们想使用别的模组(已经写好了的functions)的时候,我们就需要用到 import 这个花里胡哨的东西了(除非你比较牛逼,想自己体验一下啥都自己写的感觉,那当我没说哈哈哈哈)。在下面我给出了Haskell的basic libraries,就主动点,都自己点进去看看啦,找到modules的分类(在那个模组(Modules)里面的每一个link都写上了这个模组包含的function之类的,当你用完import 导入完之后就可以想怎么用就怎么用啦!)

Haskell模组大全(请痛击这个网址!!!)

在顺便把这几个常用的import的Modules直接po出来
Haskell Data.Listhackage.haskell.org
Haskell Data.Charhackage.haskell.org


(2)从上面找到你想要导入的包之后,就直接开始在你的编辑器上操作吧!

在这里我们找到了Data.List,上面包含了像++,head,last,length,reverse 等一系列的functions。如果想知道怎么使用,就去看看我之前给出的网址吧,在zvon上输入function名字就可以看到使用方法啦!

import Data.List
import Data.Char

halfBoth :: [Char] -> [Char] -> [Char]
halfBoth str1 str2 
    | (length str1) `mod` 2 == 0 && (length str2) `mod` 2 == 0  = (take ((length str1)`div`2) str1) ++ (take ((length str2)`div`2) str2)
    | otherwise = [(head str1)] ++ [(head str2)]

首先,我们先导入了Data.List和Data.Char,然后写了一个function(halfBoth),并且这个函数在接受完两个list of Char之后会还给我们一个list of Char。如果两个list的长度都是偶数的话,我们就取两个list的前面一半,然后把他们相加。如果有一个list的长度是偶数,那我们就把两个list的第一个元素相加。

那最后出来就是这样啦!

是不是很贴心?


二丶拓展操作

讲完了最最基本的模组操作,然后更好玩的东西来了!你们肯定会好奇怎么整一些花里胡哨的操作吧(没有不想这个选项,我就要说!好好看操作!)

(1)在ghci控制台中装载模组

如果我们想调用一个Data.List中的函数,我们可以这样玩

ghci>:m Data.List

:m 这个指令,就可以装载了,那接下来你可以直接在控制台中使用这个模组里面的函数了。

那你接下来可能会纠结,如果我想同时输入多个模组呢?还要全部都输入:m吗?

不!你可以这么玩

ghci>:m Data.List Data.Char Data.Set

这样全都可以一次性导入,就提升了咱的效率了(就不用一个个打,太麻烦了)

(2)只调用一个模组的部分函数!

这个情况一般只发生在,你已经写好自己的helper function,但是你发现重复名字了,系统不让你用,这个时候你有四个选项。第一个是改名(我是弟弟,我改名哈哈哈);第二个是用 () 找出你需要的函数

import Data.List(head,init,sort)

这两种写法都是可以的。

第三种的话,我们可以调用除了这个函数之外,模组中的其他所有函数。

假设我们的自定义function里面已经被叫做sort了,然后又导入了Data.List

那我们就这样写

import Data.List hiding(sort)

至于第四种,相对就比较恶心一点,是 qualified import

Data.Map 模组提供一了一个按键索值的数据结构,它里面有几个和 Prelude 模组重名的函数。如 filter 和 null,装入 Data.Map 模组之后再调用 filter,Haskell就不知道它究竟是哪个函数了

所以在这里,如果我们可以写一个

import qualified Data.Map
至此之后,haskell就不会冲突了,但是每次当你需要调用Data.Map里面的filter的时候
你就需要写全名了,也就是  Data.Map.filter

或者你可以这么写
import qualified Data.Map as M
这样的话,这个Data.Map就被M替换了
你就可以这样调用了
M.filter
最后再附上一个haskell的定义与使用模组的小扩充吧!冲!
Haskell Tutorial(17)定義與使用模組openhome.cc图标

其实正常来说,等讲完模组之后才应该讲data和type的使用的第二章(type和data的使用),但是我觉得,最开始讲完基本类型之后,其实就可以开始串讲data和type的使用啦!但是这篇教程的确出的比较晚,希望大家能够谅解,那至此,haskell最最基本的小入门就到这里啦!我接下来就会接着去考虑更新IO还是java的小入门课(大概率选IO,毕竟要出满一个系列哈哈哈哈),请有看到这里的各位看看还有什么遗漏,联系我之后我会补上去的,然后有问题的可以加我的微信 Gray-ray 能解答的部分我会尽量解答的!祝武运昌盛 ,开开心心预祝在国内和国外的小伙伴们学业有成,过年快乐呀!

编辑于 2020-01-09

文章被以下专栏收录