从函数式编程异常处理到薛定谔类型 -- 函数式编程本质(I)

首先说明一下

这里并不打算展开讲函数式异常处理

因为这篇文章的主题是介绍薛定谔类型.

关于前者我推荐medium上的一篇文章"Functional Error Handling".

本文很大程度上是受到这篇文章的启发

一句话来说

很多语言都有自己函数式处理异常的方式

也许你已经用过了

只是没有认识到这一点而已:

  1. Typescript的Union类型
  2. Swif的Option类型
  3. Haskell的Maybe类型

如果要给这种类型下个定义

那就是薛定谔类型(非公式说法)

怎么用薛定谔类型处理空指针异常?

这里用Typescript作为例子

如果一个函数没有处理Null会怎样:

答案是编译器会报错

我们通过Union类型杜绝了出现空指针异常的可能性

从薛定谔类型异常处理看本质

从表象上看

我们通过编译器报错

回避了空指针异常

但是这个现象的本质是什么?

我会告诉你:

如果使用函数式编程, 且输入是合法的(排除非法数据导致异常的可能性,比如除以输入0),就能够回避所有的异常

你可能会说:这怎么可能?

但是这是事实

下面是推理过程:

  1. 函数式编程的函数是纯函数,对于任何合法输入,都有唯一确定的输出.
  2. 纯函数没有副作用,不会改变函数域外的变量(杜绝了绝大部分稀奇古怪的异常).

根据以上定义

将纯函数看作一个map

对于任意合法的key 都存在唯一一个对应value

所以请你告诉我y = map[key]这样一个简单的操作如何发生异常?

你会说:

要求输入合法是犯规啊!

现实中怎么能这样处理问题?

那么请你把纯函数看作一个数学函数y = f(x)

合法的key其实就是符合定义域的x

从这个角度去思考

你就不会纠结"合法key"这样一个定义了

可能你还会反驳

我在面向对象编程里

如果有合法输入也不会发生异常啊!

可是这是错的

无论你在函数里throw一个异常

或者是改一些全局变量

或者执行了一句"rm -rf /"

都有十足的可能发生异常

而纯函数杜绝了这些可能性.

纯函数通过消灭了可变性,回归数学,构造了一个绝对稳定,逻辑严谨的系统。

可是问题随之而来: 一个不变的系统,如何反应一个持续变化的客观世界?

也许这样说的太玄乎

举个例子:

在c语言里我用getChar()函数来获取用户的输入

先别纠结函数是不是写错了因为我也好久没用c了

这个操作本身是没有问题的

刚学写程序的人最熟悉这个

可是有人不乐意了

他们是函数式编程的推崇者

一群有洁癖的人(我不是在贬低他们,有洁癖的人最值得尊敬)

他们说:

getChar的输入永远为空

可是输出却有许多可能

这根本不是一个纯函数!

我们函数式编程不能容忍这种东西的存在!

所以问题就暴露了出来: 一个不变的系统,如何反应一个持续变化的客观世界(用户输入)?

如果有人告诉你是Monad

请你打断他的腿(Monad我会另找时间介绍, 我发现网上的说法很容易误导人)

真正的答案是薛定谔类型

薛定谔类型: 数学与现实世界的桥梁

在函数式世界里,我们用薛定谔类型表现一个持续变化的世界

如果以用户输入为例子

在Haskell里这个薛定谔类型就是IO

怎么理解IO呢?

我们可以认为它是一个所有用户输入的集合

但是在取出来之前

谁都不知道里面是什么

所以它是一个薛定谔类型

这里最重要的问题在于

纯函数是如何处理薛定谔类型的?

接下来我不用IO作为例子

因为我们通常用一个变量去接住这个输入,比如:

palindrome <- getLine

然后再用这个变量作为函数输入

这样一来函数就跟薛定谔类型(在这里就是IO)解耦了

起不到说明作用

我会以Maybe Num作为例子

假设一个有一个函数名叫maybeAdd2

接受一个MaybeNum类型作为输入

MaybeNum类型可能为null也可能为某个数字

下面是它的实现(原谅我用typescript作为例子):

编译通过了

我们得到了一个处理薛定谔类型的函数!

这是非常了不起的

因为: 所有不确定的东西都可以用薛定谔类型表示

所以: 我们能处理现实世界的东西(We can deal with the f**king real world)

可是你可能会问: 这个真的是纯函数吗, 看起来不大像啊?

很好的问题

如果不符合纯函数

我们就又回到了交互式编程

函数式洁癖者也不会认同这种东西的存在

下面是推理:

输入maybe 2 => 输出maybe 4

输入maybe 3 => 输出maybe 5

输入maybe 4 => 输出maybe 6

...

好了这下你应该会同意这个函数是纯函数了.

下一篇文章我会谈谈Monad

也许这个系列就只有两篇文章

也许更多也说不定

我花了不少时间去码字

希望看完有帮助的能点个??

原文地址:https://www.cnblogs.com/uturobako/p/functional-exception-catch.html

时间: 2024-11-03 21:21:57

从函数式编程异常处理到薛定谔类型 -- 函数式编程本质(I)的相关文章

ACM大一练习赛-第三场------C - 薛定谔的猫《打表枚举的方法》

C - 薛定谔的猫 Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Edward, a poor copy typist, is a user of the Dvorak Layout. But now he has only a QWERTY Keyboard with a broken Caps Lock key, so Edward ne

生命是什么? E.薛定谔

生命是什么?——活细胞的物理学观 E.薛定谔 序 言 第一章 古典物理学家对这个主题的探讨 1. 研究的一般性质和目的 2. 统计物理学 结构上的根本差别 3. 朴素物理学家对这个主题的探讨 4. 为什么原子是如此之小? 5. 有机体的活动需要精确的物理学定律 6. 物理学定律是以原子统计学为根据的,因而只是近似的 7. 它们的精确性是以大量原子的介入为基础的.第一个例子(顺磁性) 8. 第二个例子(布朗运动,扩散) 9. 第三个例子(测量准确性的限度)  10. 根号n律 第二章 遗传机制 1

薛定谔波动方程怎么在MathType中进行编辑

在物理学中有很多经典的公式,而MathType数学公式编辑器强大的公式编辑能力能够非常完美的输入这些公式,以薛定谔波动方程为例,我们该在MathType中如何进行编辑呢? 若有疑问可直接访问:http://www.mathtype.cn/jiqiao/bodong-fangcheng.html 薛定谔波动方程示例 具体步骤如下:        1.打开MathType编辑窗口后,利用键盘输入i,在"杂项符号"模板中选择"普朗克常量"输入. 在"杂项符号&q

最伟大的游戏是“薛定谔的猫”

网游和单机的最大的不同,并非现在的游戏可以联网,大家能一起玩,而是游戏的随机性使其变得更加不可预测. 文/张书乐 原载于<人民邮电报>2016年5月20日<乐游记>专栏103期 什么样的游戏才足够有魅力?关于这个问题,我决定先掉个书袋,从"薛定谔的猫"这个物理学假说谈起.实际上,我并不想用物理学,而想用豆瓣网友创造出来的那个搞笑演绎法,曾在"学霸"."学渣"圈都一度风靡的"薛定谔撩妹法".该法并不复杂,

薛定谔的猫

薛定谔的猫实验,是有前提条件的,就是符合量子力学的随机触发装置. 在一个封闭的盒子里,有一只猫,和一个装满毒气的装置.装置有50%的概率开启,如果开启的话,装置内的毒气会杀死盒子里的猫. 好,现在回到这个前提条件,就是装置的随机性.这50%的概率,不是简简单单的投一枚硬币,50%几率正面,50%几率反面这么简单.假如你只是投一枚硬币的话,那么你的掷出力度.掷出角度.硬币旋转的线速度,空气阻力,硬币旋转产生的空气动力,甚至是硬币表面的分子分部.地球的地转偏向力,任何细微的数据全部集中在一起,经过庞

windows10简单试用(多图,连薛定谔的猫都杀死了)

为了大家看起来方便,我的截图都是gif的,比较小,但是颜色会有色差,相信大家不介意的 昨天windows10可以下载第一时间就下了玩玩 由于是技术预览,所以不打算替换之前的系统,只装在虚拟机里玩玩就好了 虚拟机我分配了2个核心 30g硬盘 4G内存 载入ios一路安装都非常顺利,相信博客园的朋友安装windows都了解这里就不讲了 装好后分辨率有点问题,我的笔记本是1377*768的 但是选不了,可能是驱动不兼容吧 资源管理器 进入系统第一眼发现的就是 图标变了 还有资源管理器的侧边栏有些变化

翻译连载 | 附录 C:函数式编程函数库-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱:分享,是 CSS 里最闪耀的一瞥:总结,是 JavaScript 中最严谨的逻辑.经过捶打磨练,成就了本书的中文版.本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走的更顺畅.比心. 译者团队(排名不分先后):阿希.blueken.brucecham.cfanlife.d

C++ socket编程——3种方法发送不同类型的数据

socket传送数据,一般来讲是char型的,如何传送我们需要的数据类型勒? 1.结构体:2, Json序列化,3. 定义一个class. 1.结构体 相对来说简单点,看看网上的一个例子: 假设需要传送的结构体如下: struct person{ char name[20]; int age; float high; }; 可在发送数据的地方对数据进行处理,将其转换成一个字符串进行传送,而在接受方定义相同的结构体对这个字符串进行解析即可. 发送方代码如下: char temp[100];   

网络编程(二):戏说非阻塞网络编程

著作权归作者所有. 商业转载请联系作者获得授权非商业转载请注明出处.作者大家可以看我的知乎专栏链接http://zhuanlan.zhihu.com/auxten/20204159这是一个系列的文章之三之四已经写完了会陆陆续续搬到Linuxtone着急的同学可以看 网络编程三从libevent到事件通知机制 网络编程四互联网中TCP Socket服务器的实现过程需要考虑哪些安全问题 在数据加密领域举例子我们经常会提到Alice和Bob我们也继续延续这种传统. 在遥远的1752年的英国电报这种可以