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

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

每种实现都是一种不同类型的 Monad。 例如,你可能阅读 "Identity Monad"、"IO Monad"、"Maybe Monad"、"Either Monad" 或其他形形色色的字眼。...所有的方法都会创建一个新的 Monad 实例而不是改变它。 Maybe 是这两个 Monad 的结合。如果一个值是非空的,它是 Just(..)...并不是一个 Monad,而是一个产生 Maybe Monad 实例的工厂函数。 Humble 是一个使用 Maybe 来跟踪 egoLevel 数字状态的数据结构包装。...的调用传入了 bob 自身的级别(41),并且创建了一个被其余的方法包装Monad 实例。在 这个 Monad 中调用的 ap(alice) 调用了 alice.map(..)...这里尝试做一个更好的解释:Monad 是一个用更具有声明式的方式围绕一个值来组织行为的方法。 和这本书中的其他部分一样,在有用的地方使用 Monad,不要因为每个人都在函数式编程中讨论他们而使用他们。

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

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

或return,将一个对象x嵌入到单子中: unit(x) :: T -> M T 组合子,典型的叫做bind(约束变量的那个bind),并表示为中缀算子>>=,去包装一个单体变量,接着把它插入到一个单体函数...可以直接这样理解:Monad 是一种特殊的数据结构,它能把值进行包装,然后链接执行;王垠在《对函数式语言的误解》中准确了描述了 Monad 本质: Monad 本质是使用类型系统的“重载”(overloading...可以看到,确实很像: Promise 也是构造函数; Promise.Resolve ,相当于 Monad unit,用于包装返回值; Promise.prototype.then 相当于 Monad...bind,用于链接执行; Promise 等效于把函数进行包装,Promise.resolve 等效于把这个包装进行拆开,将为一个普通的值; 不过,Promise 不都是 Monad,示例 Promise.resolve...,所以无法与外部进行 IO 操作,不能存在 a -> IOIO -> a 这种操作,必须为 IO -> IO(Promise -> Promise),也就是必须为「自函子」,async 函数中都是自函子映射

99220

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

写在前面 最早接触过IO Monad,后来又了解了Maybe Monad和List Monad,实际上还有很多Monad(比如Writer Monad、Reader Monad、State Monad...Identity where m >>= k = k (runIdentity m) 看起来没什么用,仔细看一下:声明了一个叫做Identity的包装类型,还实现了Monad,return的行为是把给定值包起来...从Monad实现来看,从左侧取出值a和附加信息w,将右侧函数应用到a上,并从结果取出值b和附加信息w',结果值为b,附加信息为w `mappend` w',最后用return包装结果返回m类型的值,作为...的值(a)包进了Either,并添上异常信息(e),同时保证Monad类型正确(仍然是m) throwE把错误信息用Left转成Either,再用return包装成想要的Monad,最后塞给ExceptT...a -> m a,用来把IO提升到要求的Monad上下文(在上例中是ExceptT)里: Lift a computation from the IO monad.

1.5K40

泛函编程(32)-泛函IOIO Monad

IO Monad就是泛函编程处理副作用代码的一种手段。...只有这个IO类型的解译(interpreter)在运算这个IO值时才会真正产生相应的副作用。...现在,有了这个IO类型,我们可以放心地用函数组合的泛函编程方式围绕着这个IO类型来编写IO程序,因为我们知道通过这个IO类型我们把副作用的产生推延到IO程序之外的IO解译里,而IO编程与解译是两个各自独立的程序...def apply[A](a: A) = unit(a) //IO构建,可以实现 IO {...} 6 } 既然IO类型是个Monad类型,那么我们就可以使用monadic语言编程了: 1 def...我们现在可以创建一个F类型的实例然后运算IO: 1 trait Console[A] 2 case object ReadLine extends Console[Option[String]]

2.4K70

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

Value 2 -- Value 5 同样,柯里化的操作也是OK的 (Value (*)) Value 2 Value 3 -- Value 6 此外,为了将函数“装”进容器,还需要一个包装函数的函数...在IO操作中,这个优势还可以变得更加的明显。Haskell采用Monad实现IO相关的API,这个Monad就称为IO Monad。...通过Do表记可以写出很多符合直觉的代码,比如 main :: IO () main = do putStrLn "Hello" putStr "Plz enter your name: "...Haskell中的IO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前的结果。对于部分IO Monad(如putStrLn返回的),我们直接就抛弃了这些返回值。...而Monad的计算流程是可变的,这也意味着它的计算有“上下文”。一般的计算场景中都是有上下文的,比如IO运算。但是这种没有依赖的计算场景其实也是存在的,比如并发、Parser。

77810

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

比如这样:Option[A] >>> IO[Option[A]] >>> IO[Either[String,Option[A]]。恰恰,Monad是不支持函数组合的。...但想深一层,如果其中一个Monad是会产生副作用的如IO[Option[A]],那么上面的例子就变成这样: 1 for { 2 optionData <- IO 3 } yield { 4 for...但我们必须先创建一个新的类型(不是通过函数组合的新类型)。难道我们在使用不同要求的for-comprehension时都需要重新创建一个新类型吗,这样不就损失了FP的代码重复使用特点了吗?...type lambda来表示Result[A]: type Result[A] = OptionT[({type l[x] = \/[String,x]})#l,A] 不过这样写不但复杂,而且会影响编译的类型推导...我们如何去构建Monad Transformer类型值呢?我们可以用Applicative[MT].point或者直接用构建方式如OptionT(...)

75860

JavaScript函数式编程之函子

我们可以把函子想象成一个盒子,盒子里面封装了一个值 想要处理盒子中的值,我们需要给盒子的map方法传递一个处理值的函数(纯函数),由这个函数来对值进行处理 最终map方法返回一个包含新值所在的盒子(函子) 根据函子的定义我们创建一个函子..._value)) } } 此时就已经创建了一个函子但是这是面向对象的方式来创建的,换成用函数式编程来写一个函子 class Container { constructor (value) {...,正常的就按照正常的方式创建,错误的是是否我们把map方法改造一下让她不再处理回调函数,直接返回一个空值的MayBe函子,这样就记录下了错误信息Eitcher 函子就是来处理这种情况的 Either函子..._value()) IO 函子内部帮我们包装了一些函数,当我们传递函数的时候有可能这个函数是一个不纯的操作,不管这个函数纯与不纯,IO这个函子在执行的过程中它返回的这个结果始终是一个纯的操作,我们调用map..._value)) } } Monad函子 解决函子嵌套的问题,Monad 函子是可以变扁的 Pointed 函子 IO(IO),一个函子如果具有join和of两个方法并遵循一些定律就是一个Monad

1.1K30

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

我们知道,任何涉及IO的运算都会面临堆栈溢出问题。这是因为IO通常针对无法预计的数据量以及重复循环操作。所以IO算法设计也会采用与Trampoline一样的数据结构。...或者我们应该沿用Trampoline数据结构和算法来设计IO组件库。如此思考那么我们就必须对Trampoline进行深度抽象了。Free Monad就是Trampline的延伸。...包括IO操作,也就是说可以进行一些含有副作用(side effect)的操作。那么这个函数是无法实现函数组合(function composition)。...Free Monad的两项功能分别是Monad,和Interpreter(解译)。我们用Monad描述程序算法,用Interpreter解译程序形成针对特定运行环境的可运行代码。...如果我们用Free Monad来解决IO问题的话,堆栈溢出问题也是无法避免的。我们应该考虑在Free Monad里使用Trampoline类型。

1.1K70

实现TypeScript运行时类型检查

(Input/Output, 比如网络请求, 文件读取)数据进行类型检验.io-ts社区上有很多库提供了"对数据进行校验"这个功能, 但我们今天重点讲讲io-ts.io-ts 的特殊点在于:io-ts...generator有本质上的区别.本文会着重带领读者实现io-ts 的核心模块, 是对"如何使用组合子进行抽象"的实战讲解.基础抽象作为一个解析(或者称为校验), 我们可以将其类型表示为:interface...effect)进行收集.最直接的方式是抛出一个异常(Error), 但该方式会导致整个解析被终止.我们希望能够将一个个"小"解析组合成"大"解析, 所以不希望"大"解析中的某一个"小解析"的失败...Promise>): Promise>;让我们从Promise.all这个特例推导出这个函数的普遍性抽象.Promise.all的执行逻辑(示例所用, 并非node底层实现)如下:创建一个空的...能够对一系列上下文进行串联并且收集其中的值.Monad在Applicative的基础上, 能够基于一个上下文中的值, 灵活地创建另外一个包裹在上下文中的值. -- stackoverflow上的回答在Promise.all

2.4K30

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

IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。到目前为止,我们的Monad都是针对数据的。这句话对也不对,因为函数也是一种数据(函数是第一公民)。...现在,如果我们有一个单子叫IO,并且它有如下表现: 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...IO类型让我们可以在Monad空间处理那些烦人的副作用,这个Monad类型和Promise(限定副作用到Promise域处理,可链式调用,可用then折叠和映射)很像。...可能的调用栈溢出问题 惰性计算在一些电脑或特种程序架构上可能有函数调用栈错误(超长调用链、超长递归),另外许多函数式编程语言需要编译支持尾递归优化(优化为循环迭代)以得到更好的性能。...FAQ Q:你觉得Promise是不是一种Monad IO模型? A:我认为是的。纯函数是没有异步概念的,Promise用了一种很棒的方式把异步和IO转化为了.then函数。

43810

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

3.2 范畴、群、幺半群 3.3 Monad范畴:定律、折叠和链 3.4 Maybe和Either 3.5 IO的处理方式 4....3.5 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。到目前为止,我们的Monad都是针对数据的。这句话对也不对,因为函数也是一种数据(函数是第一公民)。...现在,如果我们有一个单子叫IO,并且它有如下表现: 图 64 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...可能的调用栈溢出问题 惰性计算在一些电脑或特种程序架构上可能有函数调用栈错误(超长调用链、超长递归),另外许多函数式编程语言需要编译支持尾递归优化(优化为循环迭代)以得到更好的性能。...FAQ Q:你觉得Promise是不是一种Monad IO模型? A:我认为是的。纯函数是没有异步概念的,Promise用了一种很棒的方式把异步和IO转化为了.then函数。

89330

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

函数包装是非必需的。...这些屋子就是单子 —— “Monad”!...王垠在《对函数式语言的误解》中准确了描述了 Monad 本质: Monad 本质是使用类型系统的“重载”(overloading),把这些多出来的参数和返回值,掩盖在类型里面。...上述的 Monad 只是最通俗的理解,实际上 Monad 还有很多分类,比如:Maybe 单子、List 单子、IO 单子、Writer 单子等,后面再讨论~ 结语 本篇从纯函数出发,JavaScript...OK,以上便是本篇分享,专栏第 3 篇,希望各位工友喜欢~ 欢迎点赞、收藏、评论 后文会重点讲 延迟处理的思想、JavaScript 迭代、函数式编程中的异步等,敬请期待~ 关注专栏 # JavaScript

38910

基于线程与基于事件的并发编程之争

这其实假象,有人创建一个可扩展到100,000的线程库,其性能匹配SEDA的基于事件实现的性能。 线程限制流程控制?...线程派认为现代服务虽然需要并发处理大量的请求,但是代码处理每个请求通常是有顺序的,我们相信线程提供这两种情况下很好的编程抽象。...因为绿色线程被封装在语言的API中,因此相比Node.JS显式处理异步IO,GO语言提供了隐式的异步处理IO,从而使得并发异步变得简单。...Haskell倡导者提出通过语言统一多线程编程和事件编程,提供一种Monad函数,其内部封装了事件和多线程抽象,无论你是哪派粉丝,都可以使用这个Monad编程。 ?...这种观点得到大多数人的同意,这时被冷落一边的Scala的Actor模型站出来认为自己的Actor函数属于这种两者合一的Monad函数。

1.1K10

不可变的状态

从上面的定义可以大致看出 unit 是一个 Monad 的构造,对于 M 类型的 Monad 而言,如果将 unit 应用于一个 T 类型的值,那么它将构造一个 M[T] 类型的值。...所以,我们可以类似地定义一个类型来代表所有能产生 IO 的操作,然后将这个类型实现为一个 Monad,并在其上进行操作,这里将其命名为 IO: class IO[A](val run: () => A)...只不过 IO 所管理的状态不是一个变量而是程序与整个世界之间交互的所有 IO 操作。在 Haskell 中,IO Monad 是一个基础的 Monad 6。...而在这样的环境下,Haskell 产生输入输出这样的副作用的方式就是使用 IO Monad。...并且,由于 Int 被封装在 IO Monad 中,现在已经无法直接获取其值,调用 f 的代码的返回值也要用 IO Monad 封装起来,这又会造成新一轮的 IO Monad 的传播。

97020
领券