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

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

在轻量级函数式编程中我确实没有遇到太多需要仔细考虑 Monad 的问题,这就是本文更有价值的原因。但是并不是说 Monad 是没用的或者是不普遍的 —— 恰恰相反,它很有用,也很流行。...每种实现都是一种不同类型的 Monad。 例如,你可能阅读 "Identity Monad"、"IO Monad"、"Maybe Monad"、"Either Monad" 或其他形形色色的字眼。...Maybe 在函数式编程中,像 Maybe 这样涵盖 Monad 是很普遍的。事实上,Maybe Monad 是另外两个更简单的 Monad 的搭配:Just 和 Nothing。...在 这个 Monad 中调用的 ap(alice) 调用了 alice.map(..),并且传递给来自 Monad 的函数。...这里尝试做一个更好的解释:Monad 是一个用更具有声明式的方式围绕一个值来组织行为的方法。 和这本书中的其他部分一样,在有用的地方使用 Monad,不要因为每个人都在函数式编程中讨论他们而使用他们。

96960

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

React Hooks的设计是很巧妙的,以useEffect为例: 图 43 在函数组件中,useState用来产生状态,在使用useEffect的时候,我们需要挂载这个state到第二个参数,而第一个参数给到的运行函数在...其他的编程语言特性,在函数式编程中也能找到对应的影子,比如循环结构,我们往往使用函数递归来实现。 3.5 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。...现在,如果我们有一个单子叫IO,并且它有如下表现: 图 64 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...举个例子,面向对象里面的继承,我在函数式编程中可以使用组合compose或者高阶函数hoc来实现。 尽管在实现上是等价的,但和面向对象的编程范式对比,函数式编程有很多优点值得大家去尝试。...你仍然可以在.then函数中写纯粹的函数,也可以在.then函数中调用其他的Promise,这就和IO Monad的行为非常像。

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

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

    React Hooks的设计是很巧妙的,以useEffect为例: 在函数组件中,useState用来产生状态,在使用useEffect的时候,我们需要挂载这个state到第二个参数,而第一个参数给到的运行函数在...其他的编程语言特性,在函数式编程中也能找到对应的影子,比如循环结构,我们往往使用函数递归来实现。 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。...现在,如果我们有一个单子叫IO,并且它有如下表现: 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...在函数式语言中,我们要构建一个个小的基础函数,并通过一些通用的流程把他们粘合起来。举个例子,面向对象里面的继承,我在函数式编程中可以使用组合compose或者高阶函数hoc来实现。...你仍然可以在.then函数中写纯粹的函数,也可以在.then函数中调用其他的Promise,这就和IO Monad的行为非常像。

    49310

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

    怕生词概念的同学先别慌,先告诉你 Monad 和 Promise 很像,增点亲切感; 浅尝 Monad 在函数式编程中我们一直强调:纯函数、纯函数、纯函数!无副作用,无副作用,无副作用!...直接上代码,看看 Monad 在实际应用中是怎么写的: var fs = require("fs"); // 纯函数,传入 filename,返回 Monad 对象 var readFile = function...,被 Monad 函数包裹住含副作用的函数,根本就和纯函数是一样一样的,因为: 你无法知道一间黑色的房间里面有没有一只黑色的猫; 在编程开发中,尤其是多人协作中,一个数据要经过各种计算、加入各种逻辑...可以直接这样理解:Monad 是一种特殊的数据结构,它能把值进行包装,然后链接执行;王垠在《对函数式语言的误解》中准确了描述了 Monad 本质: Monad 本质是使用类型系统的“重载”(overloading...推荐阅读 函数式语言的宗教 图解 Monad JS 中 Monad 学习函数式编程 Monad monadic.ts 如何解释 Haskell 中的单子(Monad)

    1.1K20

    泛函编程(30)-泛函IO:Free Monad-Monad生产线

    数据结构是在heap上的,所以可以实现以heap换stack的效果。这种以数据结构代替函数调用来解决问题的方式又为泛函编程提供了更广阔的发展空间。    ...我们知道,任何涉及IO的运算都会面临堆栈溢出问题。这是因为IO通常针对无法预计的数据量以及重复循环操作。所以IO算法设计也会采用与Trampoline一样的数据结构。...在介绍Free Monad之前我们先从一个现实的例子来展开讨论: 假设我们要编写一个银行转账的函数,我们可能先把这个函数的款式(function signature)推导出来: 1 def transfer...那么这个函数是无法实现函数组合(function composition)。transfer函数就不是一个泛函编程人员该使用的函数了。...主要目的是解决泛函算法中不可避免的堆栈溢出问题。如果我们用Free Monad来解决IO问题的话,堆栈溢出问题也是无法避免的。我们应该考虑在Free Monad里使用Trampoline类型。

    1.1K70

    让Monad来得更猛烈些吧_Haskell笔记11

    这让我们在 Haskell 中可以容易地处理状态性的问题,并让其他部份的程序还是保持纯粹性。...且看随机数的示例 随机数与State Monad 就场景而言,随机数需要维护状态(随机数种子),非常适合用State Monad来处理 具体的,之前在随机数的场景,通过给random函数换不同的随机数种子来生成随机数...:: MonadIO m => IO a -> m a,用来把IO提升到要求的Monad上下文(在上例中是ExceptT)里: Lift a computation from the IO monad...五.Monad的魅力 Monad能够赋予计算一些额外的能力,比如: Writer Monad:能够把函数转换成带日志的版本,用来追踪执行过程,或者给数据变换添加额外的信息 Reader Monad:能够让一系列函数在一个可控的共享环境中协同工作...Monad的意义在于,从这些常见场景中抽象出通用模式,以简化操作,比如状态维护、日志收集等都能够通过Monad自动完成 单从使用的角度来看,用Monad包一下(没错,就这么简单),就能获得额外的能力,

    1.5K40

    当我们谈论Monad的时候(二)

    不过由于列表可以是任意长的,因此需要定义一个链状的结构 data List a = Nil | Cons a (List a) infixr 5 `Cons` 在Haskell中,用`包裹的函数可以作为中缀函数使用...Do-notation Do表记(do-notation)是Haskell给Monad操作提供的语法糖。在不使用Do表记情况下,使用Monad的代码是相当混乱的。...在IO操作中,这个优势还可以变得更加的明显。Haskell采用Monad实现IO相关的API,这个Monad就称为IO Monad。...Haskell中的IO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前的结果。对于部分IO Monad(如putStrLn返回的),我们直接就抛弃了这些返回值。...而且在范畴论中,Monad也是这么定义的。

    81310

    Scalaz(25)- Monad: Monad Transformer-叠加Monad效果

    比如这样:Option[A] >>> IO[Option[A]] >>> IO[Either[String,Option[A]]。恰恰,Monad是不支持函数组合的。...难道我们在使用不同要求的for-comprehension时都需要重新创建一个新类型吗,这样不就损失了FP的代码重复使用特点了吗?...而我们在操作时如在for-comprehension中运算时使用的类型则必须统一为OptionT[Either,A]。 我们如何去构建Monad Transformer类型值呢?...与重新构建另一个类型不同的是,通过Monad Transformer叠加Monad组合形成类型的操作依然使用各组成Monad的操作函数,这些函数运算结果类型任然是对应的Monad类型,所以需要一些升格函数...的确,用Monad Transformer组合Monad后可以实现成员Monad的效果叠加。 不过,在实际应用中两层以上的Monad组合还是比较普遍的。

    79460

    学习函数式编程 Monad

    在函数式编程中,Monad 是一种结构化程序的抽象,我们通过三个部分来理解一下。...Monad 定义 Monad 使用场景 Monad 一句话解释 Monad 定义 根据维基百科的定义,Monad 由以下三个部分组成: 一个类型构造函数(M),可以构建出一元类型 M。...Ok,我们已经明白了 Monad 的内部结构,接下来,我们再看一下 Monad 的使用场景。 Monad 使用场景 通过 Monad 的规则,衍生出了许多使用场景。 组装多个函数,实现链式操作。...包裹异步 IO 等副作用函数,放在最后一步执行。 还记得 Jquery 时代的 ajax 操作吗?...Monad 中的 unit,在 Promise 中可以看为:x => Promise.resolve(x) Monad 中的 bind,在 Promise 中可以看为:Promise.prototype.then

    75820

    不可变的状态

    如果你自己设计了一个 Monad,也必须使对应的两个函数满足 Monad law,否则用户在使用这个类型的时候就无法获得他期望的行为。这里的定义是符合 Monad law 的,可以手工推导验证一下。...对于状态获取函数 getS 而言,由于我们想获得状态,那显然这个类型就应该是 S 了,也就是说我们在状态转换的过程中并不产生其他类型的值,而是直接将当前状态本身作为转换过程的产物。...只不过 IO 所管理的状态不是一个变量而是程序与整个世界之间交互的所有 IO 操作。在 Haskell 中,IO Monad 是一个基础的 Monad 6。...Haskell 声称它是一个纯函数式的语言,也就是说你写的函数都是数学上的纯函数(除了少数后门之外),接收一个值,返回一个值,不能做其他操作。...并且,由于 Int 被封装在 IO Monad 中,现在已经无法直接获取其值,调用 f 的代码的返回值也要用 IO Monad 封装起来,这又会造成新一轮的 IO Monad 的传播。

    98820

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

    上面的Tower[IvoryTower]是状态切换函数的输入类型,不参与实际运算(不在任何运算中调用如: rw -> a),起一种状态标签作用(state tag)。...再者,函数unsafePerformIO是通过private函数apply先构建了Trampoline后再进行运算的。换言之IO Monad的用户是无法自定义算法(interpreter)的。...IO Monad可以使我们更方便地在IO这个壳子里进行我们熟悉的行令编程(imperative programming),因为我们只需要把行令程序直接放进IO里就行了。...不要被IO[A]的IO字面误导了,IO[A]的这个A不一定是副作用命令,任何行令编程使用的语句都可以放人IO[_],包括变量申明、赋值、文件读写等。...所以我们说IO Monad就是在FP模式中进行行令编程的通用方式。可以想象我们可能会在IO这个壳子内进行我们熟悉的程序编写。那么IO Monad到底能不能符合在FP环境内的行令编程要求呢?

    1.6K90

    泛函编程(27)-泛函编程模式-Monad Transformer

    在前面对这些数据类型的探讨中我们发现: 1、Monoid的主要用途是在进行折叠(Foldable)算法时对可折叠结构内元素进行函数施用(function application)、 2、Functor可以对任何高阶数据类型...不同的是施用函数是包嵌在高阶类型的(F[A => B])。Applicative可以对所有可游览结构(Traversable),包括可折叠结构(Foldable),嵌入的元素进行函数施用。...泛函编程与传统的行令编程在模式上最大的分别就是在泛函编程中没有变量声明(variable declaration),变量是包嵌在一个结构里的(MyData(data)),得申明这个结构(trait MyData...所以泛函编程的命令执行都是在一些结构内部进行的。Monad组件库中的组件主要支持这种结构内部运算风格。...我们先看看MaybeT的类型款式:  caseclass MaybeT[M[_],A](run: M[Maybe[A]]) 这是Monad Transformer通用款式 我们把共同使用的Monad包嵌在参数里

    1.3K70

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

    interpreter),把描述解译成有副作用的指令 在泛函编程中我们会持续进行这种函数分解(factoring),把含有副作用的代码分解提取出来向外推形成一个副作用代码层。...泛函模式的IO编程就是把IO功能表达和IO副作用产生分开设计:IO功能描述使用基于IO Monad的Monadic编程语言,充分利用函数组合进行。...在以上的讨论过程中我们得出了这样的结论:F类型代表了IO类型的Interpreter,我们不需要知道它到底产生副作用与否或者怎样产生。我们用F类型来把副作用的使用推延到F类型的实例。...在解译的过程中逐步用flatMap运行非纯代码。 我们可以用Free Monad的结构替代IO类型结构,这样我们就可以用Monadic编程语言来描述IO程序。...在以上例子里我们采用了Id Monad作为Interpreter语言。Id Monad的flatMap不做任何事情,所以IO程序被直接对应到基本IO函数readLine, println上了。

    2.5K70

    铁定不纯的IO_Haskell笔记5

    -> t a -> m () 在I/O List的场景,mapM第一个参数是输入a输出IO b的函数,第二个参数是[a],返回IO [b],返回值类型与sequence一致。...把处理结果写入文件,符合预期 四.System.IO 之前使用的getLine、putStrLn都是System.IO模块里的函数,常用的还有: -- 输出 print :: Show a => a -...惰性I/O 字符串本身是一个惰性List,getContents也是惰性I/O,不会一次性读入内容放到内存中 toUpperCase'的示例中会一行一行读入再输出大写版本,因为只在输出的时候才真正需要这些输入数据...handle组成的二元组 openTempFile :: FilePath -> String -> IO (FilePath, Handle) -- 定义在System.Directory模块中,用来删除指定文件...-> IO () 注意,其中removeFile和renameFile都是System.Directory模块定义的(而不是System.IO中的),文件增删改查,权限管理等函数都在System.Directory

    1.3K30

    Scalaz(34)- Free :算法-Interpretation

    Free的两个结构Suspend,Return分别代表了Monad的基本操作函数flatMap,point,我特别强调结构的意思是希望大家能意识到那就是内存heap上的一块空间。...好了,现在我们看看如何用fold来运算prg:fold需要两个入参数:r:A=>B,一个在运算终止Return状态时运行的函数,另一个是s:S[Free[S,A]]=>B,这个函数在Suspend状态时运算入参数...在Suspend Question状态下,运算f(readLine)产生下一个运算。在这个函数里我们赋予了提示、读取正真的意义,它们都是通过IO操作println,readLine实现的。...foldMap使用了Monad.bind连续通过高阶类型转换(natural transformation)将ADT转换成运行指令,并在转换过程中实施运算: 1 object QuizConsole...这个例子同样用IO函数来实现AST功能。

    75160

    Haskell爬虫中日志记录:监控HTTP请求与响应

    在当今信息爆炸的时代,数据抓取成为了获取信息的重要手段。Haskell,以其强大的类型系统和函数式编程特性,成为了编写高效、可靠爬虫的理想选择。然而,随着爬虫的运行,监控其行为变得尤为重要。...相关日志记录过程如下:集成monad-logger首先,需要在项目的.cabal文件中添加monad-logger和log包的依赖:日志记录器使用monad-logger,可以定义一个日志记录器,它将被用于记录...以下是一个简单的控制台日志后端实现:集成到爬虫主函数将日志记录集成到爬虫的主函数中,确保所有HTTP交互都被记录:代码实现以下是本文中提到的Haskell爬虫日志记录的完整实现代码:{-# LANGUAGE...编写的爬虫中实现日志记录的重要性和方法。...日志记录不仅可以帮助开发者监控爬虫的行为,还可以在出现问题时提供调试信息。使用monad-logger和log包,我们可以轻松地在Haskell中实现灵活且强大的日志记录

    12910

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

    > [4,5] xs.splice(0,3); //=> [] 例子 在React生态中,使用纯函数的例子很常见,如React Redner函数,Redux的reducer,Redux-saga的声明式...,所以非常便于移植,你可以在任何地方使用它而不需要附带着引入其他不需要的属性。...return sendRequest(host, fixPath, path) } 总结 科里化和偏函数的主要用途是在组合中,这一小节主要介绍了他们的使用方法和行为。...React中的高阶组件 在React中,有许多使用高阶组件的地方,如React-router的withRouter函数,React-redux的connect函数返回的函数, // Navbar 和...Function] },它并没有执行,而是简单地把我们想要的操作存了起来,只有当我们在真的需要这个值得时候,IO 才会真的开始求值, functor 范畴 functor 的概念来自于范畴学,并满足一些定律

    1.8K40

    Monad_Haskell笔记10

    (non-deterministic computation),而IO a代表会有side-effects的computation。...Just 1 登场: > Just (+1) (Just 1) Just 2 Monad 在Applicative之上的增强,能够把一个输入普通值输出具有context值的函数,应用到一个具有...context的值 (>>=) :: (Monad m) => m a -> (a -> m b) -> m b 如果你有一个具有context的值m a,你能如何把他丢进一个只接受普通值a的函数中,并回传一个具有...在do表示法中的作用 把Monad laws换成do表示法描述的话,就能得到另一组等价转换规则: -- Left identity do { x′ <- return x; f x′ } ≡...,应对一些通用场景,比如错误处理,I/O,不确定结果数量的计算等等,其存在意义是:比Applicative更灵活,允许在每一步计算中添加控制,像Linux管道一样 参考资料 Monad The forall

    74150
    领券