小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
前言
书接上文,我们要进行上文的maybe
函子的优化啦!
上一章传送门:juejin.cn/post/701840…
什么是Either
函子
Either
两者中的任何一个,类似于if...else...
的处理- 异常会让函数变得不纯,
Either
函子可以用来做异常处理
开始处理
1. 需求确定
磨刀不误砍柴工,我们要先明确一下需求 解决maybe函子不能确定null出现位置的函子。不仅处理什么地方出现的null,也可以用来获取异常出现的位置和异常的信息。 ok,是时候开始实现Either
函子了,因为他是二选一,所以我们要创建两个类型left
和right
```js
class left {
...
}
class right {
...
}
```
2. 类编写
在这两个类中,我们对其进行方法体的编写,它们都需要一个静态方法、一个map
方法,就是简单的函子,可以回顾:简单函子编写
```js
class Left {
static of (value) {
return new Left(value)
}
constructor (value) {
this._value = value
}
map (fn) {
return this
}
}
class Right {
static of (value) {
return new Right(value)
}
constructor (value) {
this._value = value
}
map (fn) {
return Right.of(fn(this._value))
}
}
```
到这,这两个类我们已经编写完毕了,其实我们观察一下其实都是差不多的,我们其实可以进行一下修改,不过,现在就不进行修改,这样方便大家理解
3. 函子的区别
我们用上面实现的两个类实现两个函子,我们来观察一下他们有什么区别
```js
let r1 = Right.of(12).map(x => x + 2)
let r2 = Left.of(12).map(x => x + 2)
console.log(r1)
console.log(r2)
```
我们可以看到Right
中的值是 12+2 = 14
正确的输出的,但是Left
却是返回了原来的参数,主要是因为Left
中的map
是直接返回了this
Left直接返回原来的函子,用来捕捉异常,Right用来在没有异常的时候执行输入的fn并返回一个函子。
**为什么要这么做呢?**
4. 为什么需要两种函子
为了解决上面的疑问,来个例子给大家演示一下,方便加深理解
例如传入一个会报错的JSON对象和正常的JSON对象,区别如下:
```js
function parseJSON (str) {
try {
return Right.of(JSON.parse(str))
} catch (e) {
return Left.of({ error: e.message})
}
}
// 会出现错误的情况
let r = parseJSON('{ name: zs}')
console.log(r)
let r1 = parseJSON(JSON.stringify({ name:'zs'} ))
console.log(r)
```
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/472abe33d8004bb9998ddfd576a1fc5f~tplv-k3u1fbpfcp-watermark.image?)
5. 小结
到这,Either函子 就已经演示完毕了,我们可以通过这个函子处理异常,存储错误信息
either
函子本质上就是两个函子组合的,一个函子走正确的逻辑,另外一个函子用来捕捉错误信息
完整代码
class Left {
static of (value) {
return new Left(value)
}
constructor (value) {
this._value = value
}
map (fn) {
return this
}
}
class Right {
static of (value) {
return new Right(value)
}
constructor (value) {
this._value = value
}
map (fn) {
return Right.of(fn(this._value))
}
}
//定义一个函数
function parseJSON (str) {
try {
return Right.of(JSON.parse(str))
} catch (e) {
//用来存储错误信息
return Left.of({ error: e.message})
}
}
// 传入错误的数据
let r = parseJSON('{ name: zs}')
console.log(r)
// 传入正确的数据
let r1 = parseJSON(JSON.stringify({ name:'zs'} ))
console.log(r1)
let r3 = Right.of(12).map(x => x + 2)
console.log(r3)
let r4 = Left.of(12).map(x => x + 2)
console.log(r4)
总结
本篇我们学会了Either函子
并且了解了他的构成,在之后我们准备深入函子学习,进入IO函子
篇,下一章再见!
来到这里的看官老爷给个赞吧!