首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

纯函数与领域模型

一旦去掉副作用,调用函数返回结果就与直接使用返回结果具有相同效果,二者可以互相替换,这称之为“引用透明(referential transparency)”。...如果说面向对象设计需要将依赖尽可能向外推,最终采用依赖注入方式来降低耦合;那么,函数式编程思想就是要利用纯函数来隔离变化与不变,内部由无副作用纯函数组成,纯函数将副作用向外推,形成由不变业务内核与可变副作用外围组成结构...具有引用透明特征纯函数更加贴近数学中函数概念:没有计算,只有转换。转换操作不会修改输入参数值,只是基于某种规则把输入参数值转换为输出。...Monad操作。...它本质上是Monad语法糖,组合了flatMap、map与filter等函数;但从语法上看,却类似一个for循环,这就使得我们多了一种可读性更强调用Monad形式。

1.1K10

【单子】说白了不过就是【自函子范畴】上一个【幺半群】而已?请说人话!!

怕生词概念同学先别慌,先告诉你 Monad 和 Promise 很像,增点亲切感; 浅尝 Monad 在函数式编程中我们一直强调:纯函数、纯函数、纯函数!无副作用,无副作用,无副作用!...我们即使不能一直写纯纯纯函数,不过,尽可能把这些副作用操作放在最后去执行(延迟处理、惰性处理),这也是函数式编程书写纯函数原则之一! 而实现这种做法靠就是 Monad!.../xxx.txt").bind(tail).bind(print); // 执行到这里,整个操作都是纯,因为副作用函数一直被包裹在 Monad 里,并没有执行 monad.value(); // 执行副作用函数...代码来源-孟思行 我们用 Monad 将包含副作用函数得操作进行封装,到绑定链式操作时候,都并没有执行任何副作用操作; 直到最后,调用 monad.value() 才执行了这些副作用操作; 在外界看来...,被 Monad 函数包裹住含副作用函数,根本就和纯函数是一样一样,因为: 你无法知道一间黑色房间里面有没有一只黑色猫; 在编程开发中,尤其是多人协作中,一个数据要经过各种计算、加入各种逻辑

1K20
您找到你想要的搜索结果了吗?
是的
没有找到

不可变状态

例如说我们想要实现这样一个函数,这个函数将遍历一棵二叉树,并给其每一个树叶打上标签 1,二叉树定义如下: sealed trait Tree[A] case class Leaf[A](value:...(left, right) => Branch(labelTree(left), labelTree(right)) } 这个处理很简单直接,就是维护一个变量 i,当函数 labelTree 遍历一棵树时候...回忆一下,我们在封装可变状态这一副作用时候是怎么做?我们将状态转变从隐式提升到显式在类型中展现,通过 Monad flatMap 操作来使得状态转换可以不需要手工管理。...而在这样环境下,Haskell 产生输入输出这样副作用方式就是使用 IO Monad。...将副作用提升到类型缺点 既然将副作用提升到类型上有如此大优点,为什么这样设计语言占比如此之低呢?原因是太麻烦。

97420

学习函数式编程 Monad

如果你用过 rxjs,就能体会到链式操作带来快乐。 链式操作可以消除中间状态,实现 Pointfree 风格。 处理副作用。 包裹异步 IO 等副作用函数,放在最后一步执行。...Monad 处理副作用 接下来,我们再看一个常见问题:为什么 Monad 适合处理副作用?...❝ps:这里说副作用,指的是违反纯函数原则操作,我们应该尽可能避免这些操作,或者把这些操作放在最后去执行。.../xxx.txt").bind(tail).bind(print); // 执行到这里,整个操作都是纯,因为副作用函数一直被包裹在 Monad 里,并没有执行 monad.value(); // 执行副作用函数...上面代码中,我们将副作用函数封装到 Monad 里,以保证纯函数优良特性,巧妙地化解了副作用存在安全隐患。

71520

泛函编程(32)-泛函IO:IO Monad

IO Monad就是泛函编程处理副作用代码一种手段。...泛函模式IO编程就是把IO功能表达和IO副作用产生分开设计:IO功能描述使用基于IO MonadMonadic编程语言,充分利用函数组合进行。...Free功能由Monad和Interpreter两部分组成:Monad部分使我们可以使用Monadic编程语言来描述一些算法,Interpreter就是F类型,必须是个Functor,它负责描述副作用行为...至于实际IO副作用如何,我们只知道产生副作用Interpret程序是个Monad,其它一无所知。...:IO类型可以用Free类型代替,这样我们可以充分利用Free MonadMonadic编程语言编写IO程序,我们又可以分开考虑编写可能产生IO副作用Interpreter。

2.4K70

✨从纯函数讲起,一窥最深刻函子 Monad

由纯函数概念衍生,我们将进一步探讨: 函数输入和输出 函数副作用 组合函数 无形参风格编程 以及最后将一窥较难理解函子 Monad 概念 话不多说,赶紧冲了~ 点赞 + 收藏 + 关注 === 学会...副作用 除了保障相同输入得到相同输出这一点外,纯函数还要求:不会产生任何可观察副作用副作用指当调用函数时,除了返回可能函数值之外,还对主调用函数产生附加影响。...其实我们也能看出只有纯函数组合才能更利于写出无形参风格代码,看起来更优雅~ Monad 前面一直强调:纯函数!无副作用! 谈何容易?...}; // 纯函数,传入 x,返回 Monad 对象 var tail = function (x) { // 副作用函数:返回最后一行数据 const tailFn = () => {.../xxx.txt").bind(tail).bind(print); // 执行到这里,整个操作都是纯,因为副作用函数一直被包裹在 Monad 里,并没有执行 monad.value(); // 执行副作用函数

39710

深入理解函数式编程(下)

同时,文末列举比较一些此范式优缺点,供读者参考。 1. 前文回顾 2. 本文简介 3. 副作用处理:单子Monad,一种不可避免抽象 3.1 什么是Monad?...但我们也指出了一个实际问题:不能处理副作用程序是毫无意义。我们计算机程序随时都在产生副作用。...本文主要分为三个部分: 副作用处理方式 函数式编程应用 函数式编程优缺点比较 3. 副作用处理:单子Monad,一种不可避免抽象 上面说,都是最基础JavaScript概念+函数式编程概念。...现在,如果我们有一个单子叫IO,并且它有如下表现: 图 64 我们把这种类型Monad称为IO,我们在IO中处理打印(副作用)。...IO类型让我们可以在Monad空间处理那些烦人副作用,这个Monad类型和Promise(限定副作用到Promise域处理,可链式调用,可用then折叠和映射)很像。 4.

90830

深入理解函数式编程(下)

我们计算机程序随时都在产生副作用。我们程序里面有大量网络请求、多媒体输入输出、内部状态、全局状态等,甚至在提倡“碳中和”今天,电脑发热量也是一个不容小觑副作用。...本文主要分为三个部分: 副作用处理方式 函数式编程应用 函数式编程优缺点比较 副作用处理:单子 Monad,一种不可避免抽象 上面说,都是最基础 JavaScript 概念+函数式编程概念。...而实际上,函数式编程语言确实也是这么做,把副作用包裹到一个特殊函数里面。...现在,如果我们有一个单子叫IO,并且它有如下表现: 我们把这种类型Monad称为IO,我们在IO中处理打印(副作用)。...IO类型让我们可以在Monad空间处理那些烦人副作用,这个Monad类型和Promise(限定副作用到Promise域处理,可链式调用,可用then折叠和映射)很像。

45510

Scalaz(41)- Free :IO Monad-Free特定版本FP语法

没有IO程序就是一段烧CPU代码,没有任何意义,所以任何类型程序都必须具备IO功能,而在FP模式中对IO操作有特别的控制方式:具体实现是通过把代码中产生副作用部分抽离出来延后运算(在所有纯代码运算之后...scalazIO Monad就是处理副作用代码延后运算一种数据结构。我先举个简单例子来示范如何通过一种数据结构来实现对副作用代码延迟运算:人机交互是一种典型IO,有键盘输入,又有显示屏输出。...Monad当然复杂多。...不要被IO[A]IO字面误导了,IO[A]这个A不一定是副作用命令,任何行令编程使用语句都可以放人IO[_],包括变量申明、赋值、文件读写等。...所以我们说IO Monad就是在FP模式中进行行令编程通用方式。可以想象我们可能会在IO这个壳子内进行我们熟悉程序编写。那么IO Monad到底能不能符合在FP环境内行令编程要求呢?

1.6K90

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

每种实现都是一种不同类型 Monad。 例如,你可能阅读 "Identity Monad"、"IO Monad"、"Maybe Monad"、"Either Monad" 或其他形形色色字眼。...) .chain( learn( "recursion" ) ) .chain( learn( "map/reduce" ) ) .map( introduction ); // 学习闭包 // 学习副作用...learn( "map/reduce" ) ) .chain( share( "map/reduce" ) ) .map( introduction ); // 学习闭包 // 分享闭包 // 学习副作用...// 分享副作用 // 学习递归 // 分享递归 // 学习 map/reduce // 分享 map/reduce // 我只是一个像你一样学习者 :) 在学习中分享。...这里尝试做一个更好解释:Monad 是一个用更具有声明式方式围绕一个值来组织行为方法。 和这本书中其他部分一样,在有用地方使用 Monad,不要因为每个人都在函数式编程中讨论他们而使用他们。

94260

Js-函数式编程 前言什么是函数式编程为什么Js支持FP纯函数柯里化组合 compose范畴学functorMonadApplicative FunctorFunctorMonadApplic

纯函数 概念 纯函数是这样一种函数,即相同输入,永远会得到相同输出,而且没有任何可观察副作用。...副作用包括但不限于: 打印/log 发送一个http请求 可变数据 DOM查询 简单一句话, 即只要是与函数外部环境发生交互都是副作用。...参考saga官方文档就知道了, 答案是测试: 这些 声明式调用(declarative calls) 优势是,我们可以通过简单地遍历 Generator 并在 yield 后成功值上面做一个...一个可以将普通类型转换为具有上下文函数, 即Contanier.of 拥有bind函数(即上面提到bind, 而不是ES5bind) 那么Promise具备了什么条件?...拥有容器 Promise, 即上面第一点 Promise.resolve(value)将值转换为一个具有上下文值, 即上面第二点。

1.7K40

当我们谈论Monad时候(二)

对于列表,fmap作用就是遍历每一个列表元素,并对它们应用传入函数f。...因此我们可以遍历所有可能函数-值组合,因此我们只需要两次lmap。比如对于给定函数列表fx与值列表xs,lmap (`lmap` xs) fx先遍历fx再遍历xs。...我们之前实现List在处理多参数时会遍历所有可能组合(笛卡尔积),而ZipList更贴近使用习惯,它会按照同一个位置元素来遍历多个列表。...由于“按位置遍历操作用liftA2很容易就能表达,因此我们可以直接使用liftA2来定义。...但是由于上一篇文章Applicative拖到了这篇,导致可以讲内容大大增加。所以最终这篇文章就变成几乎纯实现Monad介绍了,而关于Monad应用、副作用等等的话题就要另开一篇了。

78710

鹅厂原创 | 前端中函数式编程

直接看例子更容易理解: 从上面的代码能看出一些问题来,对于命令式编程来讲,我们需要关注对数据操作,如何创建数组,如何遍历元素,如何插入元素等等。...函数式编程中对于monad有一整套完善操作,可以将异步函数和同步函数统一起来,完美地支持函数组合。目前已经有类似的库来完成封装,比如RxJS,xstream 等。...dom细节(渲染实际上是一种副作用),只保留了最纯粹映射关系。...最终我们不得不承认,一个完美的项目其实离不开副作用(比如前端dom操作,ajax请求等都属于副作用)。...FRP中通过构建一种特殊 monad,这种 monad 可以通过被观察/订阅方式(即响应式编程方式)来抽离副作用

71720

前端中函数式编程

"(可共享可修改变量是所有罪恶根源) 纯函数(pure function)概念就是指没有副作用函数,在理论上它等价于我们数学世界里面的函数概念。...,如何创建数组,如何遍历元素,如何插入元素等等。...函数式编程中对于monad有一整套完善操作,可以将异步函数和同步函数统一起来,完美地支持函数组合。目前已经有类似的库来完成封装,比如RxJS,xstream 等。...最终我们不得不承认,一个完美的项目其实离不开副作用(比如前端dom操作,ajax请求等都属于副作用)。...FRP中通过构建一种特殊 monad,这种 monad 可以通过被观察/订阅方式(即响应式编程方式)来抽离副作用

1.4K00

Monadic Function_Haskell笔记12

- m1; return (f x1) } 等价于: liftM' f m = m >>= \x -> return (f x) 注意,这个实现并不依赖Functor特性,仅靠Monad具有的行为就可以完成...(并且如果遵守Monad laws的话,就与fmap完全等价,仅将函数应用到具有context值上,不做任何多余事情),从这个角度看,Monad比Functor更强大 已经证明了Monad比Functor...计算能够产生多个结果,因此,对powerset场景而言,求幂集一种有效方式是:遍历集合中每个元素,进行两种操作(保留它和丢掉它),并把操作结果收集起来 再看filterM实现: filterM...)时去掉,遍历时添上。...像是return,接受普通值,返回具有context值 一步步看,其中f'类型是: f' :: Monad m => t -> (a -> m b) -> a -> m b 而foldr类型是:

90530

Scalaz(28)- ST Monad :FP方式适用变量

Scalaz提供了专门解决可变量使用问题方法,能保证即使在并行运算环境内各线程无法影响相互间可变量,即ST Monad。...x <- read(i) _ <- write(i, f(x, v)) } yield () } 我们看到STRef和STArray都定义了write,mod,update这样有副作用操作函数...ST Monad与State Monad最大不同是它没有run方法,也就是我们无法用ST内部方法来获取ST[S,A]A值。...可以预见,如果我们通过某些方式能获取一个内存地址的话,就有可能在函数体外对地址内值进行修改,也就造成了副作用产生。...与State Monad比较,ST Monad并不包含为获取运算值而设run函数。ST Monad在类型外定义了读取运算值函数runST。

53080

Scalaz(54)- scalaz-stream: 函数式多线程编程模式-Free Streaming Programming Model

通过一段时间对函数式编程方法学习,我们了解到Free Monad算式/算法关注分离(separation of concern)可以是一种很实用函数式编程模式。...用Free Monad编写程序容易理解并具备良好可维护性。scalaz-stream流程控制和多线程运算模式可以实现程序安全并行运算。...不过如果直接运行foldMapRec有可能会产生副作用(siede effect)。这样不符合纯代码要求,无法实现这个程序与其它程序函数组合。...我们需要把这段可能产生副作用代码放到Task里: 1 val taskGetName = Task.delay { prgGetName.foldMapRec(InteractConsole)} 2...Free Monad和scalar-stream可以很好集成在一起。

55460

深入理解JavaScript函数式编程

JavaScript中高阶函数 ❝高阶函数 ❞ 函数作为参数,如下代码实现是循环遍历数组,通过传递参数回调函数可以拿到每个数组遍历值在回调函数中进行相应处理 //模拟forEach function...这些问题引入了函子概念 Fuctor函子 容器:包含值和值变形关系(这个变形关系就是函数) 函子:是一个特殊容器,通过一个普通对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理...Monad函子 IO函子问题,在业务逻辑遇到函子嵌套情况IO(IO(x)); Monad就是解决函子嵌套问题。..._value(); // IO(IO(x)) console.log(r);//IO { _value: [Function] } Monad 函子是可以变扁Pointed函子 一个函子如果具有join...副作用会让一个函数变不纯,但是副作用是不可避免,因为代码难免会依赖外部文件、数据库等,只能最大程度上控制副作用在可控范围内 柯里化函数curry也是高阶函数 柯里化函数内部用到了闭包,对函数参数做了缓存

4.3K30
领券