首页
学习
活动
专区
圈层
工具
发布

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

从Monad实现来看,从左侧取出值a和附加信息w,将右侧函数应用到a上,并从结果取出值b和附加信息w',结果值为b,附加信息为w `mappend` w',最后用return包装结果返回m类型的值,作为...竟然还是Monad,其具体实现如下: instance Monad ((->) r) where f >>= k = \ r -> k (f r) r return没有额外实现,所以是Applicative...这就是State Monad的存在意义,想让状态维护变得更容易,同时不影响其它纯的部分 从实现角度看,State Monad是个函数,接受一个状态,返回一个值和新状态 s -> (a,s) -- 即 state...只是帮那些能表达错误的类型(如Either、Maybe)实现了额外的throwError和catchError,并没有做侵入式修改,但有了这两个行为,我们确实可以优雅地处理错误了,这与上面介绍的几个Monad...不同 除了Either,另一个实现了MonadError的重要实例是ExceptT(当然,不止这2个): instance Monad m => MonadError e (ExceptT e m) where

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

    Zipper_Haskell笔记13

    新牌堆仍由之前的牌构成,但与原牌堆没有任何联系,类似于状态丢弃,直接丢掉原牌堆,而不是维护修改,例如(实现数组反转的一般方法,用JS描述): function swap(arr, from, to) {...二者的差异在于,可变的数据结构中,我们把数据结构当做可扩展复用的容器,对数据结构的操作就是对容器里的值进行增、删、改;不可变的数据结构中,我们把数据结构当做数据常量,无法扩展和复用,所以对数据结构的操作相当于重新创建一份很像但不太一样的数据...实际上,局部的修改没必要重新创建整棵树,直到需要完整树的时候再去创建更合理一些。在数据结构不可变的情况下,这能实现吗?...PathWithContext与之前的Path类似,同样用来表示访问路径,只是路径的每一步除了记录方向,还记录了相应的上下文信息,包括父节点和兄弟节点 接着实现“任意穿梭”: goLeft ((Node...通用Zipper:如Zipper Monad、Generic Zipper 针对具体数据结构的Zipper我们已经实现过两个了(把xxxWithContext换成Zipper即可),大致思路是: Zipper

    62550

    实现TypeScript运行时类型检查

    .只有赋予解析器更灵活地处理异常的能力, 我们才能实现更加灵活的组合方式和错误日志的收集.此处可能有些抽象, 如果有所疑惑是正常现象, 结合下文理解会更加容易些.因此, 我们希望"能够像处理数据那样处理异常...: P1 | P2 代表输入的数据通过两个解析器中的一个.intersect: P1 & P2 代表输入的数据同时满足P1和P2两个解析器union 组合子该组合子类似于or运算:type Union...的一些操作, 罗列如下:Promise.resolvePromise.then其中的Promise.then其实是兼具了Fuctor.map和Monad.chain实现.Functor上文提到过, 让我们简单看看...Applicative这样的类型构造器的类型约束称为type class, 而Promise这样的实现了某种type class的类型称为instance of type class.如代码示例所示,...ap可以通过Monad.chain实现, 那么其意义是什么?

    2.9K30

    llvm入门教程-Kaleidoscope前端-6-用户定义运算符

    到目前为止,我们已经实现的解析器对大部分语法使用递归下降解析,对表达式使用运算符优先解析。详见第2章。...我们将把这些功能的实现分为两部分:实现对用户定义的二元运算符的支持和添加一元运算符。 用户定义的二元运算符 在我们当前的框架中,添加对用户定义的二元运算符的支持非常简单。...添加一元运算符更具挑战性,因为我们还没有任何框架-让我们看看需要什么。 用户定义的一元运算符 因为我们目前不支持Kaleidoscope语言中的一元运算符,所以我们需要添加所有内容来支持它们。...接下来,我们需要添加对原型的解析器支持,以解析一元运算符原型。...值得注意的是,可变变量是一些语言的一个重要特性,如何在不向前端添加“SSA构造”的情况下添加对可变变量的支持并不是显而易见的。在下一章中,我们将介绍如何在前端不构建SSA的情况下添加可变变量。

    1.5K20

    学习函数式编程 Monad

    Monad 定义 Monad 使用场景 Monad 一句话解释 Monad 定义 根据维基百科的定义,Monad 由以下三个部分组成: 一个类型构造函数(M),可以构建出一元类型 M。...// ps:但一些特殊的情况不满足该定义,下文中会讲到 看完上面的代码,不禁感觉很惊讶,Promise 和 Monad 也太像了吧,不仅可以实现链式操作,也满足单位元和结合律,难道 Promise 就是一个...如果是这两种情况,那就无法满足 Monad 规则。...当单位元和其他元素结合时,并不会改变那些元素。 如: 任何一个数 + 0 = 这个数本身。那么 0 就是单位元(加法单位元) 任何一个数 * 1 = 这个数本身。...总结 本文从 Monad 的维基百科开始,逐步介绍了 Monad 的内部结构以及实现原理,并通过 Promise 验证了 Monad 在实战中发挥的重大作用。

    92120

    《JavaScript函数式编程指南》读书笔记

    纯函数所具有的性质: 仅取决于提供的输入,而不依赖于任何在函数求值期间或调用间隔时可能变化的隐藏状态和外部状态。 不会造成或超出其作用域的变化。如修改全局变量对象或引用传递的参数。...柯里化:柯里化是一种在所有参数被提供之前,挂起或“延迟”函数执行,将多个参数转化为一元函数序列的技术。...就比如identity组合子其实是R.curry(identity),柯里化后的组合子操作起来更方便。 tap(K-组合子):将没有函数返回值的函数返回输入值。...:Functor和Monad。...Maybe Monad用来处理是否为空的判断逻辑。它有2个具体的类型:Just和Nothing。 Just(value)表示有值时的容器。 Nothing()表示没有值时的容器。

    1.2K43

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

    本文将探讨如何在Haskell编写的爬虫中实现日志记录,以监控HTTP请求与响应。爬虫与日志记录爬虫是一种自动浏览网络资源的程序,它可以访问网页、下载内容、提取信息,并将其存储起来。...调试问题:快速定位运行中的错误和异常。遵守政策:记录遵守robots.txt协议的情况,确保爬虫行为合规。分析效率:评估爬虫的性能和资源消耗。...相关日志记录过程如下:集成monad-logger首先,需要在项目的.cabal文件中添加monad-logger和log包的依赖:日志记录器使用monad-logger,可以定义一个日志记录器,它将被用于记录...,我们了解到在Haskell编写的爬虫中实现日志记录的重要性和方法。...日志记录不仅可以帮助开发者监控爬虫的行为,还可以在出现问题时提供调试信息。使用monad-logger和log包,我们可以轻松地在Haskell中实现灵活且强大的日志记录

    46110

    编程语言:类型系统的本质

    封装允许隐藏数据和方法,而继承则使用额外的数据和代码扩展一个类型。 封装出现在多个层次,例如,服务将其API公开为接口,模块导出其接口并隐藏实现细节,类只公开公有成员,等等。...接口类型: 抽象类和接口 我们使用接口来指定契约。接口可被扩展和组合。 接口或契约:接口(或契约)描述了实现该接口的任何对象都理解的一组消息。消息是方法,包括名称、实参和返回类型。接口没有任何状态。...代码如下: 一个简单的装饰器模式 装饰器模式是一个简单的行为软件设计模式,可扩展对象的行为,而不必修改对象的类。装饰的对象可以执行其原始实现没有提供的功能。装饰器模式如图所示。...Monad Functor 总是返回一个单层的函子,避免出现嵌套的情况。...小结 在不涉及范畴论的情况下,针对函子和单子,做一个简单的小结。 Functor 和 monad 都为包装输入提供了一些工具,返回包装后的输出。

    3.2K31

    自制计算器——《自制编程语言》二

    《自制计算器(借助yacc和lex)—《自制编程语言》一》 本文介绍下不用yacc和lex的实现过程,其实就是自己编写词法解析器和词法分析器来代替yacc和lex。...如果需要扩展并可以支持编程语言的话,最好注意以下几个要点 1.数值与标识符(如变量名等)可以按照上例的方法通过管理一个当前状态将其解析出来,比如自增运算符就可以设置一个类似IN_INCREMENT_OPERATOR...和项 * 一元表达式 */ | term DIV primary_expression /* 或 和项 / 一元表达式 */ ; primary_expression...如语法图中最开始的primary_expression一样,第41行的parse_primary_expression()会被调用。...BNF这样的语法称为左递归,原封照搬左递归的语法规则是无法实现递归下降分析的。 yacc生成的解析器称为LALR(1)解析器,这种解析器能解析的语法称为LALR(1)语法。

    2K20

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

    而就是对函数与值都进行模式匹配,在有值的情况下将值应用给函数。 对于列表来说,情况可能稍微复杂一点。因为的参数可能是多个函数和多个值。...Haskell中的IO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前的结果。对于部分IO Monad(如putStrLn返回的),我们直接就抛弃了这些返回值。...Monad的时候有没有发现,Monad好像几乎不怎么依赖于Applicative的实现。...*(如liftM2)和liftA*(如liftA2)是一致的 和ap是一致的 Traversable实际上只要求Applicative,但是实现上却要求Monad 这么多明明相同的东西却有那么多不同的表示方法...Applicative和Monad都能实现运算的组合与排序,因此它们都能对运算进行建模,但是Applicative在运算的过程中并没有上下文。

    1.2K10

    设计模式实战 - 解释器模式(Interpreter Pattern)

    负责解析符号,由两个子类 AddExpression(负责加法运算) SubExpression(负责减法运算) 解析器的开发工作已经完成了,但是需求还没有完全实现。...我们还需要对解析器进行封装, 来实现 解析的工作完成了,我们还需要把安排运行的先后顺序(加减法不用考虑,但是乘除法呢?...每个运算符号都只和自己左右两个数字有关系,但左右两个数字有可能也是一个解析的结果,无论何种类型,都是Expression的实现类,于是在对运算符解析的子类中增加了一个构造函数,传递左右两个表达式。...客户模拟类 为了满足业务要求,我们设置了一个Client类来模拟用户情况,用户要求可以扩展,可以修改公式,那就通过接收键盘事件来处理 ?...解释器是一个比较少用的模式,以下为其通用源码,可以作为参考。抽象表达式通常只有一个方法,如代码清单27-8所示。 适用场景 ? 优点 ? 缺点 ? 相关设计模式 ?

    1K20

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

    唯一的难点是,Monad要求实现的方法没有特定的功能。这比较像Comparable,而我们知道Comparable比较大小的语义纯粹只是人为增加的而已。...return this.join(result); } 在Optional的情况下,flatMap是用来实现返回值本身可能是null的函数,比如: MyMonadOptional tryParse...liftM2作用于List的效果就是一个笛卡尔积。而且你细品,这不就是列表推导式嘛。 根据这个例子,不难看出:由于高度的抽象,基于Monad编写的函数(如liftM2)本身没有“明确的用途”。...也就是说,Monad把处理数据的操作也变得不确定了。如果纸箱里有东西,我们就把它取出来处理,如没有东西就原封不动。操作的执行与否和纸箱里面的东西存在与否息息相关!...文中没有提及flatMap需要遵守的规则,对Monad的定义也不太完备(缺少了return),也没有细究join和flatMap的互相实现。要真正理解Monad,理论上的内容同样是不可避免的。

    59810

    Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern

    而不同类型的Monad实例则会支持不同的程序运算行为,如:Option Monad在运算中如果遇到None值则会中途退出;State Monad会确保状态值会伴随着程序运行流程直到终结;List Monad...Scalaz提供了很多不同种类的Monad如:StateMonad, IOMonad, ReaderMonad, WriterMonad,MonadTransformer等等,这从另一个角度也重申了Monad...所以Monad同时又是Applicative和Functor,因为Monad实现了map和ap函数。一个Monad实例可以调用所有Applicative和Functor提供的组件函数。...任何实例只需要实现抽象函数point和bind就可以成为Monad实例,然后就可以使用Monad所有的组件函数了。...] = None 超出重量平衡的情况返回了None。

    918100

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

    科学解释一个Monad为自函子范畴上的幺半群。如果没有学习群论和范畴论的话,我们是很难理解这个解释的。...Maybe和Either 有了Just的概念,我们再来学习一些新的Monad概念。比如Nothing。 Nothing表示在Monad范畴上没有的值。...和Just一起正好描述了所有的数据情况,合称为Maybe,我们的Maybe Monad要么是Just,要么是Nothing。这有什么意义呢?...并不是说函数式编程一定是优秀的,但它至少没有那么恐怖。有一点可以肯定的是,学习函数式编程可以扩展我们的思维,增加我们看问题的角度。 Q:有没有一些可以预见的好处? A:有的。...这种对比在业务复杂的情况下更加明显,面向对象必须要优秀的设计模式来实现控制代码复杂度增长不那么快,而函数式编程大多数情况下都是单向数据流+基础工具库就减少了大量的复杂度,而且产生的代码更简洁。

    64010

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

    科学解释一个Monad为自函子范畴上的幺半群。如果没有学习群论和范畴论的话,我们是很难理解这个解释的。...图 56 3.4 Maybe和Either 有了Just的概念,我们再来学习一些新的Monad概念。比如Nothing。 图 57 Nothing表示在Monad范畴上没有的值。...和Just一起正好描述了所有的数据情况,合称为Maybe,我们的Maybe Monad要么是Just,要么是Nothing。这有什么意义呢?...并不是说函数式编程一定是优秀的,但它至少没有那么恐怖。有一点可以肯定的是,学习函数式编程可以扩展我们的思维,增加我们看问题的角度。 Q:有没有一些可以预见的好处? A:有的。...这种对比在业务复杂的情况下更加明显,面向对象必须要优秀的设计模式来实现控制代码复杂度增长不那么快,而函数式编程大多数情况下都是单向数据流+基础工具库就减少了大量的复杂度,而且产生的代码更简洁。 8.

    1.2K30
    领券