00:00
在模式匹配这章的最后呢,我们再来介绍一个scla当中相对冷门一点的。概念啊,那就是所谓的偏函数这一部分呢,呃,可以给大家做一个简单的介绍,大家有所了解就可以了,因为偏函数的底层也有case语句,其实本质上它就是用了一个模式匹配,那所谓的偏函数呢,它其实也是函数的一种。真正意义上的类型写出来,它其实叫partial function,也就是翻译过来其实应该叫部分函数,可能,呃,可能更准确一点啊,然后我们看到如果完整的定义声明出来的话,它的类型后边的泛型有两个,那么一个呢是当前这个函数的输入参数类型,然后另外一个就是当前函数的返回值类型。啊,比方说像这里边我们定义了一个这个函数,呃,当然了,我们这里是把它定义成了一个变量啊,Value,因为当前它的类型叫partial function,这其实是一个一个类的对象啊,就创建了一个类的对象,那么后边它的返回值类型是option。
01:12
那我们自然想到它叫second,返回一个option int,那看起来是要返回第二个元素的值啊,那它输入是一个list int,那就是一个列表当中第二个元素的值,它怎么样来实现呢?后面我们看它的。函数题里边啊,直接就是一个case,利用一个模式匹配,后面呢,就是对应我们前边list的一个啊,这样的一个判断啊,X双冒号,Y双冒号,然后下划线,下划线表示就是剩下的那一部分,我们不关心,那那前面第一个呢,第一个元素叫X,第二个元素叫Y,最后要返回的是sum y,这不就是我们的第二个元素吗?哎,所以这种定义,这就是一个偏函数的定义,我们这里的功能就是返回。
02:03
Int类型的列表list里边的第二个元素值当然是包装成了一个萨,它如果要是nu本身是空的话,我们返回的就是no那个nu。这就是关于偏函数的一个定义,那只是这么一说的话,可能大家还是不太清楚这些东西有什么用,那其实scla当中的这个偏函数啊,大家可以理解成它是一个残缺的函数,因为它叫部分函数嘛,哎,它就像一个偏科的学生,他只对某些科目感兴趣,其他那些不感兴趣的内容呢,就完全不管了,完全不不看了啊,那所以这个爬出function啊,偏函数它也是类似,它只处理自己感兴趣的那种那种情况,那种case,所以他其实就是做了一个模式匹配的对应的分支的筛选,嗯,那一般情况呢,每一个偏函数它可能只能处理我们当前这个输入情况里边的一部分场景,所以如果要是在完整的代码里边,往往是需要把多个偏函数定义出来,然后再组合在一起,最终才做到了一个覆盖。
03:15
全部输入类型的结果。啊,那接下来我们还是在代码里边测一测,大家就知道到底是怎么回事了。接下来我们又一个SC的object object test06,我们现在测的是part,没办法写出来啊,那这里边我们先给大家看一看这个单函数的一个转换的过程吧,我们先定义一个例子出来,这是我们想要操作的一个集合。List里边的数据我们还是定义成类似于K对这样的一个二元组A啊,我们直接把前定义的这个copy过来吧。
04:01
前面我们定义过这样的一个二元组。这是我们目前的数据,然后接下来呢,那就是先做一个我们想要比方说啊,我们现在的想法是把这一个元组类型的list,想要做一个转换处理当前的。每一个元组里边第一个元素这个是KK不变,然后呢,把对应的第二个元素,也就是value,让它做一个乘二处理,哎,那我们知道这个非常简单,这不就是直接做一个map转换,直接就搞定了吗?嗯,那接下来我们就先map转换,直线D不变,Value。两倍对吧,变成变成原来的两倍一个循环啊,这里我们不用放循环,直接一个map操作就搞定了嘛,所以我们定义一个new list,基于前面的list,直接点map里面要传的操作,那就是当前我们的每一个temp,那么后转换成的一个二元组,那就是下划线一不变,然后对应的下划线二乘以二,当然了这种做法如果我们用之前在word count里边使用过的map values的话,会更加的方便,因为它只操作对应的value,这个是我们能够想到的啊呃,这个过程还是非常的简单,那其实我们如果进一步发现的话,目前的这个功能啊,我们使用模式匹配也能实现这个功能,因为之前我们不是说了模式匹配可以直。
05:51
接对于这个元组的每一个值做一个赋值操作吗?哎,所以接下接下来我们也可以用这种方式做一个实现,用模式匹配。
06:03
对元素,元素不值。直线功能,你有一个list new list2低于之前的list啊,这里我们还是做一个map。现在我们要传的呢,那就是当前这个还是参数式,然后里边我们要做的参做的这个操作,其实是可以做一个模式匹配,按当前的Apple match到底是什么样子,那我们知道1MATCH case的时候,就可以直接给它做二元组的这样一个赋值了,一个word,一个count,哎,我们找到了是这样的情况的话,那就直接把它对应的付成word count乘二就完了吗?
07:03
所以大家看这样的话,我们从代码的可读性上来讲,其实是更加的方便,更加的简洁了。但是这样的过程呢,整体看起来就会稍微的有点麻烦,我们这里边写的这个花括号,还有这个箭头什么的太多了,语法有点复杂啊,那这里其实idea也给我们做了一个提示啊,这里边其实可以直接把中间的这一部分全部都省略掉,然后我们就直接可以做一个对应的匹配了,我们看可以写写成什么样子呢?这是第三种状况。整略。省略拉达哦,而是写法。进行简化,最终里边一简化,我先把这个直接copy过来,我们看一下的变化是这个基础上直接把中间的这些都删掉了啊,那当然了,这里边。
08:09
删掉之后我们会发现map一个小括号里边其实就是花括号括着的一句case语句啊,那么在这种情况下呢,小括号也可以直接删掉。所以我们就干脆变成了一个map,后边加一个花括号,就是一句case,所以大家其实会发现了这样的一个省略之后的简略写法,直接出现case的这种写法,这表示的就是一个。不是一个偏函数,我看偏函数里边就是直接一一句case,所以我们map里边不是要传一个函数吗?我们现在传的同样是一个函数,只不过是一个偏函数而已,他输方式。好啊,那所以接下来我们可以看一下得到这个结果是不是符合我们预期new list,还有new list2list3可以做一个打印。
09:09
运行一下。我们会,我们会看到都可以把当前的这一个list里边的每一个K对应的值都乘以二,做一个打一数数啊,所以上面的这三种做法都是等价的啊,如果大家要是觉得下面这个偏函数不好理解的话,这个需求其实我们直接用上面的这种写法实现就可以了,我们这只是看一下它是怎么样得到这样一个偏函数的写法的,跟模式匹配是息息相关的啊,那这个看起来好像也没什么用啊,我们之之前用这个一个简单的map就可以搞定了,为什么要写成偏函数呢?啊,真正的偏函数,它其实就是要一部分一部分去处理当前的情形,然后最后再把所有的结合在一起,那接下来我们给大家简单的说一个函数的应用,比方说我们来做一个求绝对值的应用吧,这个很简单的一个应用,求绝对值之前我们也做过这个求绝对值的,呃,具体的这个实现用一个match case,我们判断一下当前它的范围,用模式首位去做判断,然后如果大于等于零的话,直接就是自身,如果小于零的话,那就输出它的相反数,这个我们是自然能够实现的,但是那种实现呢,其实用首位啊,整个那个代码稍微还是有点有点复杂,那能不能让这个整个代码的可读性更高呢?这里给大家提供一个偏函数的思路那。
10:52
整体来讲就是分,对输入数据分为不同的情形,那什么样的情形呢?当然就是正负零啊,当然正数和零其实可以合在一起,我们为了让大家看的更清晰,分成负零三种来做一个处理,接下来我们其实就要定义三个同啊。
11:23
偏函数,那接下来我们首先定义一个定数的处理,我们叫呃,Positive ABS绝对值的一个方法,那里边呢,直接就是一个偏函数的定义啊,函数定义的时候直接用case语句。里边当前这个X里边跟模式匹配的这个写法是完全一样的,但我们还是类似用一个呃,用一个模式守位的这样一个写法,因为只能判断它这个范围嘛,X等于零画,那么我们就直接返回X,这是我们能想到的,这里边报错,那是因为目前的语法并不知道我们想要返回一个偏函数,那这个时候呢,我们把它类型要直接定义出来,Function里边的类型呢,当前输入的数据参数是什么?当然是一个in特类型啊,返回的类型是什么?不然还是一个int类型啊,我们直接把这个定义出来,目前的语法就不报错。
12:28
这就是一部分,大于零的这一部分,那是正数求绝对值,同样道理,接下来我们可以定义负数求绝对值negative ABS,那这里同样啊,要判断就是if小于零的话,那这里边给的就是一个负X,好,那同样我们还可以定义一个。专门定义一个0AABS,那就是呃,这个就不用这么复杂了啊,我们直接判断当前如果是零的话,那就直接接着输出零可以了啊,那最终我们要把这个组合在一起,那应该怎么调用呢?呃,这个调用的方式其实就非常的有趣,我们组合起来这个方这个啊,呃,当前的这个函数啊,就叫做自己定义的ABS啊,那是传一个整形的数X进来返回,它的绝对值是一个整数,那它具体的实现应该怎么定义呢?我们干脆一句话就可以搞定了。
13:34
里边我们写的就是首先positive ABS,然后or else,因为大家想到它并不能完全处理好我们的所有场景嘛。接下来是for else。Negative ABS,然后all else zero ABS啊,那最后当然就是把我们的这个X作为参数要进去,就可以得到最后的一个in类型的返回,当然了,这相当于我们是把前面的这一部分啊,作为了一个整体和到了一个完整的函数,因为每一部分都是一个偏函数嘛,部分函数,所以用这样的一个调用一个一个返回,得到一个完整的函数,再把当前X传进去,就可以得到最终的绝对值了。
14:29
哎,所以这个定义还是有点,呃,就是相当于我们写了一句这个英文的,英文的一句话啊,就可以把这个完整的函数表表示出来了,这就是函数式编程的另外的一个魅力啊,那这里边我们看到else当然是一个方法调用了啊,他到底是干了一个什么事呢?其实在这儿它是又拗了一个all else这样的一个对象,那本身我们看到all else呢啊。目前啊,这个all else,它本身也是一个。
15:01
偏函数也是一个部分函数啊,它其实就相当于是要把我们的两个部分函数要做一个判断的整合,我们要把它整合在一起啊,最终就实现了不同偏函数不同部分的合并,那最后我们可以做一个测试。咱们测一下吧,ABS直接掉。比方说给一个负67,那另外可以ABS给一个正数35,另外ABS0。运行的话,会得到们各自的绝对值,这就是我们对于偏函数的一个理解。
我来说两句